Skip to content

SD2 1118 make eden ai chat api open ai compatible #329

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged

Conversation

juandavidcruzgomez
Copy link
Contributor

@juandavidcruzgomez juandavidcruzgomez commented Mar 3, 2025

  • Amazon chat feature
  • Amazon chat feature
  • Amazon chat feature
  • Amazon chat feature
  • LLM chat feature providers
  • LLM chat feature providers
  • Update the response class
  • Docs and outputs

Summary by CodeRabbit

  • New Features

    • Expanded large language model (LLM) chat functionality across multiple API providers, delivering interactive chat completions with enhanced parameter flexibility and improved response metadata.
  • Refactor & Chore

    • Numerous internal code, documentation, and formatting improvements were applied for consistency and maintainability without altering end-user behavior.

@juandavidcruzgomez juandavidcruzgomez requested a review from Daggx March 3, 2025 15:56
Copy link

coderabbitai bot commented Mar 3, 2025

Walkthrough

This pull request implements a broad integration of LLM chat functionality across multiple provider APIs while standardizing and polishing the codebase. Several API modules now inherit from a new LLM interface and include added methods (e.g., llm__chat) and standardized clients (via StdLLMEngine). New JSON output files and info sections for chat responses have been added. In parallel, numerous formatting, import, and whitespace adjustments have been made throughout tests, utilities, documentation, and various feature modules to improve readability and consistency.

Changes

File(s) Change Summary
edenai_apis/__init__.py, edenai_apis/interface_v2.py, edenai_apis/features/llm/__init__.py Exposed new LLM functionality by importing and abstracting LlmInterface (creating the LLM instance).
edenai_apis/apis/{amazon,anthropic,cohere,deepseek,google,openai,replicate,together_ai,xai,meta,mistral}/... Integrated LLM capabilities: updated class inheritance (added LlmInterface), introduced llm__chat methods, initialized StdLLMEngine clients, and updated info.json files and JSON output structures for chat completions.
edenai_apis/features/llm/{chat,chat_args,chat_dataclass,llm_interface}.py Introduced new chat-related modules, including definitions for chat arguments, data classes, and the LLM interface.
edenai_apis/llmengine/llm_engine.py Expanded PROVIDER_MAPPING to include additional providers ("bedrock_converse", "amazon") for the standard LLM engine.
Various files in edenai_apis/apis/*, edenai_apis/features/*, edenai_apis/utils/*, edenai_apis/tests/*, setup.py, .docsrc/conf.py Applied extensive formatting and style improvements (e.g., consistent import style, string delimiters, whitespace, and docstring adjustments) without affecting functionality.

Sequence Diagram(s)

sequenceDiagram
    participant U as User
    participant A as API Class (e.g., AmazonApi)
    participant S as StdLLMEngine
    participant L as LLM Service
    U->>A: Invoke llm__chat(parameters)
    A->>S: Call completion(...)
    S->>L: Process chat completion request
    L-->>S: Return chat response
    S-->>A: Return ChatDataClass
    A-->>U: Return final chat response
Loading

Poem

I'm a bouncy rabbit in the code-filled glade,
Hoping through new LLM paths we've made.
With lines and methods sleek and bright,
I nibble on each change from morning to night.
Formatting, new interfaces, all in play—
Leaping with joy in a curious way.
🐇💻 Happy hops to our revamped day!


🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Generate unit testing code for this file.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 12

🔭 Outside diff range comments (3)
edenai_apis/apis/anthropic/anthropic_api.py (1)

140-216: 🛠️ Refactor suggestion

Remove mutable default for the messages parameter.

At line 142, messages: List = [] could introduce shared-state bugs if the list is modified across calls. Replace it with None for safer defaults.

Here's a possible diff:

-def llm__chat(self,
-    messages: List = [],
-    ...
-):
+def llm__chat(self,
+    messages: Optional[List] = None,
+    ...
+):
+    if messages is None:
+        messages = []
🧰 Tools
🪛 Ruff (0.8.2)

142-142: Do not use mutable data structures for argument defaults

Replace with None; initialize within function

(B006)

edenai_apis/apis/mistral/mistral_api.py (1)

154-231: 🛠️ Refactor suggestion

Remove mutable default for messages & refine argument defaults.
The mutable default can trigger subtle bugs. Use a None default and instantiate lists inside the method.

Proposed fix:

- def llm__chat(
-     self,
-     messages: List = [],
+ def llm__chat(
+     self,
+     messages: Optional[List] = None,
      ...
):
+     if messages is None:
+         messages = []
🧰 Tools
🪛 Ruff (0.8.2)

157-157: Do not use mutable data structures for argument defaults

Replace with None; initialize within function

(B006)

edenai_apis/apis/replicate/replicate_api.py (1)

247-323: 🛠️ Refactor suggestion

Mitigate mutable default in llm__chat.
Set messages to None by default to avert unintentional side-effects.

Proposed fix:

- def llm__chat(
-     self,
-     messages: List = [],
+ def llm__chat(
+     self,
+     messages: Optional[List] = None,
      ...
):
+     if messages is None:
+         messages = []
🧰 Tools
🪛 Ruff (0.8.2)

249-249: Do not use mutable data structures for argument defaults

Replace with None; initialize within function

(B006)

🧹 Nitpick comments (17)
edenai_apis/apis/meta/info.json (1)

27-30: New LLM Chat Metadata Addition
The introduction of the "llm" section containing "chat" configuration with version "llmengine (v2)" enriches the metadata information, aligning it with other providers. Ensure that any documentation referring to metadata updates reflects these changes.

edenai_apis/features/llm/__init__.py (1)

1-2: Expose LlmInterface via all for Cleaner Exports
The import of LlmInterface in __init__.py makes it available to users of the package. However, static analysis suggests that it’s imported but not explicitly exported. To improve clarity and API usability, consider adding LlmInterface to the module’s __all__ list. This change will signal that LlmInterface is part of the public interface.

A suggested diff is as follows:

 from .llm_interface import LlmInterface
+__all__ = ['LlmInterface']
🧰 Tools
🪛 Ruff (0.8.2)

1-1: .llm_interface.LlmInterface imported but unused; consider removing, adding to __all__, or using a redundant alias

(F401)

edenai_apis/apis/amazon/amazon_api.py (1)

3-3: Fix the import path inconsistency.

The import statement uses a relative path (apis.amazon) while other imports use the full path (edenai_apis.apis). This inconsistency might cause issues in certain contexts.

-from apis.amazon.amazon_llm_api import AmazonLLMApi
+from edenai_apis.apis.amazon.amazon_llm_api import AmazonLLMApi
edenai_apis/features/llm/chat/chat_args.py (1)

3-21: Consider making the chat arguments more configurable.

The current implementation hardcodes values like model name, messages, and the image URL, which limits reusability for actual API usage beyond examples or tests.

Consider refactoring to support different use cases:

-def chat_arguments(provider_name: str):
-    return {
-        "model": "mistral/mistral-saba-latest",
-        "messages": [
-            {"role": "system", "content": "Always reply like a pirate"},
-            {
-                "role": "user",
-                "content": [
-                    {"type": "text", "text": "Describe this image please!"},
-                    {
-                        "type": "image_url",
-                        "image_url": {
-                            "url": "https://upload.wikimedia.org/wikipedia/commons/thumb/d/dd/Gfp-wisconsin-madison-the-nature-boardwalk.jpg/2560px-Gfp-wisconsin-madison-the-nature-boardwalk.jpg"
-                        },
-                    },
-                ],
-            },
-        ],
-        "temperature": 1,
-        "max_tokens": 1000,
-    }
+def chat_arguments(
+    provider_name: str = None,
+    model: str = "mistral/mistral-saba-latest",
+    system_message: str = "Always reply like a pirate",
+    user_message: str = "Describe this image please!",
+    image_url: str = "https://upload.wikimedia.org/wikipedia/commons/thumb/d/dd/Gfp-wisconsin-madison-the-nature-boardwalk.jpg/2560px-Gfp-wisconsin-madison-the-nature-boardwalk.jpg",
+    include_image: bool = True,
+    temperature: float = 1.0,
+    max_tokens: int = 1000
+):
+    """
+    Generates argument dictionary for LLM chat API calls.
+    
+    Args:
+        provider_name (str, optional): The provider name, may affect model selection.
+        model (str): The model identifier to use.
+        system_message (str): The system instruction message.
+        user_message (str): The user's text message.
+        image_url (str): URL to an image (if include_image is True).
+        include_image (bool): Whether to include an image in the content.
+        temperature (float): Sampling temperature, between 0 and 2.
+        max_tokens (int): Maximum tokens to generate.
+        
+    Returns:
+        dict: Formatted chat arguments for the LLM API.
+    """
+    messages = [{"role": "system", "content": system_message}]
+    
+    user_content = [{"type": "text", "text": user_message}]
+    if include_image and image_url:
+        user_content.append({
+            "type": "image_url",
+            "image_url": {"url": image_url}
+        })
+    
+    messages.append({"role": "user", "content": user_content})
+    
+    return {
+        "model": model,
+        "messages": messages,
+        "temperature": temperature,
+        "max_tokens": max_tokens,
+    }
edenai_apis/features/llm/chat/__init__.py (1)

1-15: Add __all__ to define public API.

These imports are meant to be re-exported as part of the package's public API. To make this explicit and avoid linter warnings, consider adding an __all__ list.

 from .chat_args import chat_arguments
 from .chat_dataclass import (
     ChatCompletionChoice,
     ChatCompletionModel,
     ChatCompletionRequest,
     ChatMessage,
     ResponseFormat,
     ChatCompletionResponse,
     ChatCompletionUsage,
     FunctionDefinition,
     ChatRole,
     ToolCall,
     ToolCallFunction,
     ToolDefinition,
 )
+
+__all__ = [
+    'chat_arguments',
+    'ChatCompletionChoice',
+    'ChatCompletionModel',
+    'ChatCompletionRequest',
+    'ChatMessage',
+    'ResponseFormat',
+    'ChatCompletionResponse',
+    'ChatCompletionUsage',
+    'FunctionDefinition',
+    'ChatRole',
+    'ToolCall',
+    'ToolCallFunction',
+    'ToolDefinition',
+]
🧰 Tools
🪛 Ruff (0.8.2)

1-1: .chat_args.chat_arguments imported but unused; consider removing, adding to __all__, or using a redundant alias

(F401)


3-3: .chat_dataclass.ChatCompletionChoice imported but unused; consider removing, adding to __all__, or using a redundant alias

(F401)


4-4: .chat_dataclass.ChatCompletionModel imported but unused; consider removing, adding to __all__, or using a redundant alias

(F401)


5-5: .chat_dataclass.ChatCompletionRequest imported but unused; consider removing, adding to __all__, or using a redundant alias

(F401)


6-6: .chat_dataclass.ChatMessage imported but unused; consider removing, adding to __all__, or using a redundant alias

(F401)


7-7: .chat_dataclass.ResponseFormat imported but unused; consider removing, adding to __all__, or using a redundant alias

(F401)


8-8: .chat_dataclass.ChatCompletionResponse imported but unused; consider removing, adding to __all__, or using a redundant alias

(F401)


9-9: .chat_dataclass.ChatCompletionUsage imported but unused; consider removing, adding to __all__, or using a redundant alias

(F401)


10-10: .chat_dataclass.FunctionDefinition imported but unused; consider removing, adding to __all__, or using a redundant alias

(F401)


11-11: .chat_dataclass.ChatRole imported but unused; consider removing, adding to __all__, or using a redundant alias

(F401)


12-12: .chat_dataclass.ToolCall imported but unused; consider removing, adding to __all__, or using a redundant alias

(F401)


13-13: .chat_dataclass.ToolCallFunction imported but unused; consider removing, adding to __all__, or using a redundant alias

(F401)


14-14: .chat_dataclass.ToolDefinition imported but unused; consider removing, adding to __all__, or using a redundant alias

(F401)

edenai_apis/apis/xai/xai_llm_api.py (2)

11-86: Consider refactoring method for better maintainability

The method has a large number of parameters with direct parameter forwarding which makes it hard to maintain. If the underlying client API changes, this method will also need to be updated. Furthermore, there are parameters marked as "soon to be deprecated" by OpenAI.

Consider one of these approaches:

  1. Use **kwargs exclusively and only extract/manipulate parameters that need special handling
  2. Group related parameters into typed dataclasses or Pydantic models
  3. Create helper methods to handle parameter transformation and validation

Example of using **kwargs:

def llm__chat(
    self,
    messages: Optional[List] = None,
    model: Optional[str] = None,
-    # Optional OpenAI params: see https://platform.openai.com/docs/api-reference/chat/create
-    timeout: Optional[Union[float, str, httpx.Timeout]] = None,
-    temperature: Optional[float] = None,
-    top_p: Optional[float] = None,
-    # ... many more parameters
    **kwargs
) -> ChatCompletionResponse:
    if messages is None:
        messages = []
    
    # Only set specific parameters explicitly
    params = {
        "messages": messages,
        "model": model,
    }
    
    # Add all other parameters
    params.update(kwargs)
    
    response = self.std_llm_client.completion(**params)
    return response
🧰 Tools
🪛 Ruff (0.8.2)

13-13: Do not use mutable data structures for argument defaults

Replace with None; initialize within function

(B006)


5-6: Use absolute imports to improve compatibility

The import for LlmInterface uses a relative import path which might cause issues in different contexts or when the package structure changes.

Update to use absolute imports:

-from features.llm.llm_interface import LlmInterface
+from edenai_apis.features.llm.llm_interface import LlmInterface
edenai_apis/apis/google/google_llm_api.py (2)

5-6: Use absolute imports to improve compatibility

The import for LlmInterface uses a relative import path which might cause issues in different contexts or when the package structure changes.

Update to use absolute imports:

-from features.llm.llm_interface import LlmInterface
+from edenai_apis.features.llm.llm_interface import LlmInterface

9-86: Code duplication with XAiLLMApi

This class implements almost identical functionality to XAiLLMApi with the only difference being how the client is accessed. This duplication increases maintenance burden.

Consider creating a base class that implements the common functionality and have both GoogleLLMApi and XAiLLMApi inherit from it. The base class could provide a method like:

def _get_llm_client(self):
    """Get the LLM client - to be implemented by subclasses"""
    raise NotImplementedError

def llm__chat(self, messages=None, model=None, **kwargs):
    if messages is None:
        messages = []
    client = self._get_llm_client()
    response = client.completion(messages=messages, model=model, **kwargs)
    return response

Then each subclass would only need to implement _get_llm_client():

class GoogleLLMApi(BaseLLMApi):
    def _get_llm_client(self):
        return self.clients["std_llm_client"]

class XAiLLMApi(BaseLLMApi):
    def _get_llm_client(self):
        return self.std_llm_client
🧰 Tools
🪛 Ruff (0.8.2)

13-13: Do not use mutable data structures for argument defaults

Replace with None; initialize within function

(B006)

edenai_apis/features/llm/llm_interface.py (2)

2-2: Remove unused Dict import.

The typing.Dict import is never utilized in this file. It should be removed for clarity and maintainability.

-from typing import Optional, List, Dict, Type, Union
+from typing import Optional, List, Type, Union
🧰 Tools
🪛 Ruff (0.8.2)

2-2: typing.Dict imported but unused

Remove unused import: typing.Dict

(F401)


55-71: Align docstring with actual parameters.

The docstring references parameters (e.g., chatbot_global_action) that are not present in the function signature. Consider removing or updating these references to maintain consistency and avoid confusion.

edenai_apis/apis/amazon/amazon_llm_api.py (1)

6-6: Remove unused imports.

These imports (MultimodalInterface, ChatDataClass, StreamChat, ChatMessageDataClass, and ResponseType) appear unused. Consider removing them to keep the codebase clean.

-from edenai_apis.features import MultimodalInterface
-from edenai_apis.features.multimodal.chat import (
-    ChatDataClass,
-    StreamChat,
-    ChatMessageDataClass,
-)
-from edenai_apis.utils.types import ResponseType

Also applies to: 8-8, 9-9, 10-10, 12-12

🧰 Tools
🪛 Ruff (0.8.2)

6-6: edenai_apis.features.MultimodalInterface imported but unused

Remove unused import: edenai_apis.features.MultimodalInterface

(F401)

edenai_apis/apis/meta/meta_api.py (1)

50-57: Consider handling potential missing or invalid credentials.
You might wrap the engine initialization in a try-except or add checks to ensure keys are present and valid.

edenai_apis/features/llm/chat/chat_dataclass.py (4)

14-30: Consider validating function_call and tool_calls structure

If function_call or tool_calls must adhere to a certain schema or reference defined functions/tools, you may add a validator to ensure these references match an existing definition, preventing runtime mismatches.


41-49: Optional: Validate function definition parameters more strictly

Currently, parameters: Dict[str, Any] is open-ended. You might consider schemas or deeper Pydantic modeling to enforce expected parameter types and shapes, providing clearer error messages for invalid definitions.


150-157: Use an Enum for finish_reason for stronger type safety

Currently, finish_reason is a bare string. Converting it to an Enum can improve consistency and help catch typos.

+ class FinishReason(str, Enum):
+     STOP = "stop"
+     LENGTH = "length"
+     TOOL_CALLS = "tool_calls"
+     CONTENT_FILTER = "content_filter"
+     FUNCTION_CALL = "function_call"

 class ChatCompletionChoice(BaseModel):
     index: int = Field(..., description="The index of this completion choice")
     message: ChatMessage = Field(..., description="The chat completion message")
-    finish_reason: str = Field(...)
+    finish_reason: FinishReason = Field(...)

186-195: Token usage details look clear

These fields provide excellent insight for debugging or billing. It might help to add small docstrings or usage examples to guide implementers.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 178aaa4 and 60c358a.

📒 Files selected for processing (47)
  • edenai_apis/__init__.py (1 hunks)
  • edenai_apis/apis/amazon/amazon_api.py (2 hunks)
  • edenai_apis/apis/amazon/amazon_llm_api.py (1 hunks)
  • edenai_apis/apis/amazon/info.json (1 hunks)
  • edenai_apis/apis/amazon/outputs/llm/chat_output.json (1 hunks)
  • edenai_apis/apis/anthropic/anthropic_api.py (4 hunks)
  • edenai_apis/apis/anthropic/info.json (1 hunks)
  • edenai_apis/apis/anthropic/outputs/llm/chat_output.json (1 hunks)
  • edenai_apis/apis/cohere/cohere_api.py (4 hunks)
  • edenai_apis/apis/cohere/info.json (1 hunks)
  • edenai_apis/apis/cohere/outputs/llm/chat_output.json (1 hunks)
  • edenai_apis/apis/deepseek/deepseek_api.py (4 hunks)
  • edenai_apis/apis/deepseek/info.json (1 hunks)
  • edenai_apis/apis/deepseek/outputs/llm/chat_output.json (1 hunks)
  • edenai_apis/apis/google/google_api.py (3 hunks)
  • edenai_apis/apis/google/google_llm_api.py (1 hunks)
  • edenai_apis/apis/google/info.json (1 hunks)
  • edenai_apis/apis/google/outputs/llm/chat_output.json (1 hunks)
  • edenai_apis/apis/meta/info.json (1 hunks)
  • edenai_apis/apis/meta/meta_api.py (4 hunks)
  • edenai_apis/apis/meta/outputs/llm/chat_output.json (1 hunks)
  • edenai_apis/apis/mistral/info.json (1 hunks)
  • edenai_apis/apis/mistral/mistral_api.py (4 hunks)
  • edenai_apis/apis/mistral/outputs/llm/chat_output.json (1 hunks)
  • edenai_apis/apis/openai/info.json (1 hunks)
  • edenai_apis/apis/openai/openai_api.py (3 hunks)
  • edenai_apis/apis/openai/openai_llm_api.py (1 hunks)
  • edenai_apis/apis/openai/outputs/llm/chat_output.json (1 hunks)
  • edenai_apis/apis/replicate/info.json (1 hunks)
  • edenai_apis/apis/replicate/outputs/llm/chat_output.json (1 hunks)
  • edenai_apis/apis/replicate/replicate_api.py (4 hunks)
  • edenai_apis/apis/together_ai/info.json (1 hunks)
  • edenai_apis/apis/together_ai/outputs/llm/chat_output.json (1 hunks)
  • edenai_apis/apis/together_ai/together_ai_api.py (4 hunks)
  • edenai_apis/apis/xai/info.json (1 hunks)
  • edenai_apis/apis/xai/outputs/llm/chat_output.json (1 hunks)
  • edenai_apis/apis/xai/xai_api.py (2 hunks)
  • edenai_apis/apis/xai/xai_llm_api.py (1 hunks)
  • edenai_apis/features/__init__.py (1 hunks)
  • edenai_apis/features/llm/__init__.py (1 hunks)
  • edenai_apis/features/llm/chat/__init__.py (1 hunks)
  • edenai_apis/features/llm/chat/chat_args.py (1 hunks)
  • edenai_apis/features/llm/chat/chat_dataclass.py (1 hunks)
  • edenai_apis/features/llm/chat/chat_response.json (1 hunks)
  • edenai_apis/features/llm/llm_interface.py (1 hunks)
  • edenai_apis/interface_v2.py (2 hunks)
  • edenai_apis/llmengine/llm_engine.py (1 hunks)
✅ Files skipped from review due to trivial changes (12)
  • edenai_apis/apis/meta/outputs/llm/chat_output.json
  • edenai_apis/apis/amazon/outputs/llm/chat_output.json
  • edenai_apis/apis/mistral/outputs/llm/chat_output.json
  • edenai_apis/apis/google/outputs/llm/chat_output.json
  • edenai_apis/features/llm/chat/chat_response.json
  • edenai_apis/apis/anthropic/outputs/llm/chat_output.json
  • edenai_apis/apis/xai/outputs/llm/chat_output.json
  • edenai_apis/apis/deepseek/outputs/llm/chat_output.json
  • edenai_apis/apis/replicate/outputs/llm/chat_output.json
  • edenai_apis/apis/cohere/outputs/llm/chat_output.json
  • edenai_apis/apis/openai/outputs/llm/chat_output.json
  • edenai_apis/apis/together_ai/outputs/llm/chat_output.json
🧰 Additional context used
🪛 Ruff (0.8.2)
edenai_apis/__init__.py

26-26: .interface_v2.Text imported but unused; consider removing, adding to __all__, or using a redundant alias

(F401)


26-26: .interface_v2.Ocr imported but unused; consider removing, adding to __all__, or using a redundant alias

(F401)


26-26: .interface_v2.Video imported but unused; consider removing, adding to __all__, or using a redundant alias

(F401)


26-26: .interface_v2.Audio imported but unused; consider removing, adding to __all__, or using a redundant alias

(F401)


26-26: .interface_v2.Image imported but unused; consider removing, adding to __all__, or using a redundant alias

(F401)


26-26: .interface_v2.Translation imported but unused; consider removing, adding to __all__, or using a redundant alias

(F401)


26-26: .interface_v2.Multimodal imported but unused; consider removing, adding to __all__, or using a redundant alias

(F401)


26-26: .interface_v2.LLM imported but unused; consider removing, adding to __all__, or using a redundant alias

(F401)

edenai_apis/apis/xai/xai_llm_api.py

13-13: Do not use mutable data structures for argument defaults

Replace with None; initialize within function

(B006)

edenai_apis/apis/openai/openai_llm_api.py

1-1: typing.Dict imported but unused

Remove unused import: typing.Dict

(F401)


3-3: openai.OpenAI imported but unused

Remove unused import: openai.OpenAI

(F401)


4-4: openai.NOT_GIVEN imported but unused

Remove unused import: openai.NOT_GIVEN

(F401)


13-13: Do not use mutable data structures for argument defaults

Replace with None; initialize within function

(B006)

edenai_apis/apis/google/google_llm_api.py

13-13: Do not use mutable data structures for argument defaults

Replace with None; initialize within function

(B006)

edenai_apis/apis/deepseek/deepseek_api.py

64-64: Do not use mutable data structures for argument defaults

Replace with None; initialize within function

(B006)

edenai_apis/apis/meta/meta_api.py

136-136: Do not use mutable data structures for argument defaults

Replace with None; initialize within function

(B006)

edenai_apis/features/llm/llm_interface.py

2-2: typing.Dict imported but unused

Remove unused import: typing.Dict

(F401)


15-15: Do not use mutable data structures for argument defaults

Replace with None; initialize within function

(B006)

edenai_apis/apis/amazon/amazon_llm_api.py

6-6: edenai_apis.features.MultimodalInterface imported but unused

Remove unused import: edenai_apis.features.MultimodalInterface

(F401)


8-8: edenai_apis.features.multimodal.chat.ChatDataClass imported but unused

Remove unused import

(F401)


9-9: edenai_apis.features.multimodal.chat.StreamChat imported but unused

Remove unused import

(F401)


10-10: edenai_apis.features.multimodal.chat.ChatMessageDataClass imported but unused

Remove unused import

(F401)


12-12: edenai_apis.utils.types.ResponseType imported but unused

Remove unused import: edenai_apis.utils.types.ResponseType

(F401)


22-22: Do not use mutable data structures for argument defaults

Replace with None; initialize within function

(B006)


38-38: Do not use mutable data structures for argument defaults

Replace with None; initialize within function

(B006)

edenai_apis/apis/together_ai/together_ai_api.py

67-67: Do not use mutable data structures for argument defaults

Replace with None; initialize within function

(B006)

edenai_apis/apis/anthropic/anthropic_api.py

142-142: Do not use mutable data structures for argument defaults

Replace with None; initialize within function

(B006)

edenai_apis/apis/cohere/cohere_api.py

336-336: Do not use mutable data structures for argument defaults

Replace with None; initialize within function

(B006)

edenai_apis/apis/replicate/replicate_api.py

249-249: Do not use mutable data structures for argument defaults

Replace with None; initialize within function

(B006)

edenai_apis/features/__init__.py

9-9: .llm.llm_interface.LlmInterface imported but unused; consider removing, adding to __all__, or using a redundant alias

(F401)

edenai_apis/apis/mistral/mistral_api.py

157-157: Do not use mutable data structures for argument defaults

Replace with None; initialize within function

(B006)

edenai_apis/features/llm/__init__.py

1-1: .llm_interface.LlmInterface imported but unused; consider removing, adding to __all__, or using a redundant alias

(F401)

edenai_apis/features/llm/chat/__init__.py

1-1: .chat_args.chat_arguments imported but unused; consider removing, adding to __all__, or using a redundant alias

(F401)


3-3: .chat_dataclass.ChatCompletionChoice imported but unused; consider removing, adding to __all__, or using a redundant alias

(F401)


4-4: .chat_dataclass.ChatCompletionModel imported but unused; consider removing, adding to __all__, or using a redundant alias

(F401)


5-5: .chat_dataclass.ChatCompletionRequest imported but unused; consider removing, adding to __all__, or using a redundant alias

(F401)


6-6: .chat_dataclass.ChatMessage imported but unused; consider removing, adding to __all__, or using a redundant alias

(F401)


7-7: .chat_dataclass.ResponseFormat imported but unused; consider removing, adding to __all__, or using a redundant alias

(F401)


8-8: .chat_dataclass.ChatCompletionResponse imported but unused; consider removing, adding to __all__, or using a redundant alias

(F401)


9-9: .chat_dataclass.ChatCompletionUsage imported but unused; consider removing, adding to __all__, or using a redundant alias

(F401)


10-10: .chat_dataclass.FunctionDefinition imported but unused; consider removing, adding to __all__, or using a redundant alias

(F401)


11-11: .chat_dataclass.ChatRole imported but unused; consider removing, adding to __all__, or using a redundant alias

(F401)


12-12: .chat_dataclass.ToolCall imported but unused; consider removing, adding to __all__, or using a redundant alias

(F401)


13-13: .chat_dataclass.ToolCallFunction imported but unused; consider removing, adding to __all__, or using a redundant alias

(F401)


14-14: .chat_dataclass.ToolDefinition imported but unused; consider removing, adding to __all__, or using a redundant alias

(F401)

⏰ Context from checks skipped due to timeout of 90000ms (1)
  • GitHub Check: test
🔇 Additional comments (56)
edenai_apis/apis/replicate/info.json (1)

31-35: New LLM Chat Configuration Added
The new "llm" section with a nested "chat" object and version "llmengine (v2)" is correctly added. This update aligns with similar modifications across other provider configuration files and enhances the API’s clarity regarding LLM chat support.

edenai_apis/apis/deepseek/info.json (1)

11-15: Consistent LLM Chat Update
The addition of the "llm" section specifying "chat" with version "llmengine (v2)" is implemented consistently. This improves the API’s configuration framework across modules without altering existing functionality.

edenai_apis/apis/mistral/info.json (1)

42-46: Updated LLM Chat Block in Mistral Module
The new block for "llm" with the "chat" version set to "llmengine (v2)" has been added correctly. This change maintains consistency with other API modules and standardizes the LLM chat feature versioning.

edenai_apis/features/__init__.py (1)

9-9: New LlmInterface introduced for chat feature integration.

This import makes the LlmInterface available to the package's namespace, providing access to the new LLM chat capability that this PR is implementing.

🧰 Tools
🪛 Ruff (0.8.2)

9-9: .llm.llm_interface.LlmInterface imported but unused; consider removing, adding to __all__, or using a redundant alias

(F401)

edenai_apis/apis/amazon/info.json (1)

848-852: Amazon LLM chat integration configured correctly.

The addition of the "llm" section with "chat" capability using "llmengine (v2)" aligns with the PR objective to make the Eden AI chat API OpenAI compatible. This configuration enables Amazon's LLM capabilities to be integrated into the platform.

edenai_apis/__init__.py (1)

26-26:

❓ Verification inconclusive

LLM entity properly exposed in the package interface.

The addition of LLM to the imports makes the Large Language Model functionality available at the package level, consistent with how other capabilities like Text, Ocr, etc. are exposed. This enables users to access LLM features using the same interface pattern as other capabilities.


🏁 Script executed:

#!/bin/bash
# Verify how the LLM class is structured and used in the codebase

# Check the interface_v2.py file to understand the LLM class definition
cat edenai_apis/interface_v2.py | grep -A 20 "class LLM"

# Find examples of how the LLM class might be used
rg "from edenai_apis import LLM" --type py
rg "LLM\." --type py

Length of output: 126


I'll need to perform an additional check because the initial commands returned no output. It might be that the LLM class definition exists in a different location or under a different syntax, or it could indicate that the LLM class isn't implemented as expected. To clarify this, please run the following command to search the entire repository for the LLM class definition:

Once we have those results, we can confidently verify that the LLM entity is properly exposed in the package interface or whether further action is needed.


🏁 Script executed:

#!/bin/bash
rg -n "class LLM" .

Length of output: 175


LLM entity alias exposure needs manual confirmation in interface_v2.py

Our repository search did not reveal a direct definition of a class named “LLM.” Instead, we found references to an LLMEngine (and its associated error) in the llmengine module. Since the package’s __init__.py imports LLM from interface_v2.py, it appears that the intended approach is to alias LLMEngine as LLM within that module. Please manually verify that edenai_apis/interface_v2.py contains an alias assignment (for example, via a line like from .llmengine.llm_engine import LLMEngine as LLM) which would correctly expose the LLM functionality at the package level.

  • Verify that interface_v2.py correctly sets up the alias (or equivalent) for LLM.
  • Confirm consistency with how other capabilities (Text, Ocr, etc.) are exposed.

Once this aliasing is confirmed, the package interface will remain consistent with the intended design.

🧰 Tools
🪛 Ruff (0.8.2)

26-26: .interface_v2.Text imported but unused; consider removing, adding to __all__, or using a redundant alias

(F401)


26-26: .interface_v2.Ocr imported but unused; consider removing, adding to __all__, or using a redundant alias

(F401)


26-26: .interface_v2.Video imported but unused; consider removing, adding to __all__, or using a redundant alias

(F401)


26-26: .interface_v2.Audio imported but unused; consider removing, adding to __all__, or using a redundant alias

(F401)


26-26: .interface_v2.Image imported but unused; consider removing, adding to __all__, or using a redundant alias

(F401)


26-26: .interface_v2.Translation imported but unused; consider removing, adding to __all__, or using a redundant alias

(F401)


26-26: .interface_v2.Multimodal imported but unused; consider removing, adding to __all__, or using a redundant alias

(F401)


26-26: .interface_v2.LLM imported but unused; consider removing, adding to __all__, or using a redundant alias

(F401)

edenai_apis/apis/together_ai/info.json (1)

11-15:

❓ Verification inconclusive

LLM chat capability added to Together AI provider.

The addition of the LLM chat configuration using "llmengine (v2)" is consistent with the changes made to Amazon's info.json, ensuring a unified approach across providers. However, there's an important distinction:

  1. There's an existing "text"/"chat" capability with version "v1" (lines 2-9)
  2. The new "llm"/"chat" capability uses "llmengine (v2)" (lines 11-15)

This suggests a deliberate separation between the traditional text chat and the new LLM-based chat functionality.


🏁 Script executed:

#!/bin/bash
# Verify the pattern of separating text/chat and llm/chat across providers

# Check how many providers have both text/chat and llm/chat capabilities
echo "Providers with both text/chat and llm/chat:"
fd ".*/info.json$" edenai_apis/apis/ -x grep -l '"text":.*"chat"' {} \; | xargs grep -l '"llm":.*"chat"'

# Check if there's a consistent version pattern for llm/chat across providers
echo -e "\nLLM chat version pattern across providers:"
rg '"llm":\s*{\s*"chat":\s*{\s*"version"' -A 1 --json edenai_apis/apis/*/info.json

Length of output: 2929


Action Required: Verify Consistency of LLM and Text Chat Configurations Across Providers

The update in edenai_apis/apis/together_ai/info.json clearly introduces a new LLM-based chat configuration ("llm": { "chat": { "version": "llmengine (v2)" } }), while keeping the traditional text-based chat (version "v1") intact. This deliberate separation aligns with similar changes seen in providers like Amazon. However, our initial automated check using regex did not yield conclusive output due to a parsing error. Please manually verify that:

  • The legacy "text": { "chat": ... } configuration (v1) remains unaltered.
  • The new "llm": { "chat": ... } configuration (v2) is correctly added and follows the repository’s unified design.
  • Other providers maintain consistent separation between the text and LLM chat capabilities.
edenai_apis/apis/xai/info.json (1)

246-250: Integration of LLM chat capability looks good.

The addition of the LLM chat feature with version specification is consistent with the overall structure of the JSON file and aligns with the PR objective of making the Eden AI Chat API compatible with OpenAI.

edenai_apis/apis/amazon/amazon_api.py (1)

27-27: LGTM - AmazonLLMApi integration is appropriate.

Adding the AmazonLLMApi to the inheritance hierarchy properly extends the AmazonApi class with LLM chat capabilities, which aligns with the PR objective.

edenai_apis/apis/openai/info.json (1)

1200-1204: OpenAI LLM chat capability looks good.

The addition of the LLM chat feature with consistent versioning ("llmengine (v2)") matches the implementation in other provider info files and supports the PR objective of standardizing chat interfaces.

edenai_apis/features/llm/chat/chat_args.py (1)

3-3:

❓ Verification inconclusive

Verify that the default model is appropriate for all providers.

The current implementation assumes "mistral/mistral-saba-latest" as the default model, but this might not be available or optimal for all providers that will implement the LLM chat interface.


🏁 Script executed:

#!/bin/bash

# Check which providers might be configured to use this model
echo "Searching for model references in LLM files..."
rg -A 5 "mistral-saba-latest" --type py

Length of output: 618


Verify Default Model Usage Across Providers

Based on the grep results, the default model "mistral/mistral-saba-latest" is solely set in edenai_apis/features/llm/chat/chat_args.py and isn’t overridden or further customized elsewhere in the codebase. This suggests that for now the chat interface always uses this default regardless of the provider. Please confirm that this hardcoded default is appropriate for every provider that implements the LLM chat interface or consider introducing provider-specific default configurations if needed.

  • The default model is only hard-coded in chat_args.py.
  • No other references or overrides for provider-specific models were found.
edenai_apis/apis/cohere/info.json (1)

70-74: New LLM chat integration looks good

The new "llm" section with the "chat" subsection is properly structured and consistent with the existing JSON format. It helps standardize the representation of chat capabilities for Cohere's LLM.

edenai_apis/apis/anthropic/info.json (1)

54-62: Well-defined model specification for Anthropic

The new "llm" section properly defines Anthropic-specific models for the chat functionality. The use of the "v1" version indicator (different from Cohere's "llmengine (v2)") suggests different implementation approaches for these providers, which is appropriate.

edenai_apis/interface_v2.py (2)

21-21: Good addition of LlmInterface import

This import enables the new LLM functionality to be integrated into the interface system.


99-99: Properly follows established pattern for interface abstraction

The addition of the LLM abstract class correctly follows the same pattern as other interfaces, ensuring consistent access to LLM functionality throughout the codebase.

edenai_apis/apis/openai/openai_api.py (4)

3-3: Appropriate import of LLM engine classes

The import of both LLMEngine and StdLLMEngine provides the necessary components for implementing OpenAI compatibility in the chat API.


10-10: Good integration of OpenAI LLM API

The import of OpenaiLLMApi allows for specific OpenAI LLM functionality to be added to the main API class.


26-26: Proper inheritance expansion

Adding OpenaiLLMApi to the inheritance chain of OpenaiApi ensures that LLM chat functionality is available through the main API interface.


58-59:

✅ Verification successful

Verify relationship between llm_client and std_llm_client

The code now has two separate LLM client instances: llm_client (existing) and std_llm_client (new). While this might be intentional to support both a custom and standard implementation, it could potentially lead to confusion.


🏁 Script executed:

#!/bin/bash
# Check where each client is used in the codebase

echo "Checking where llm_client is used:"
rg -A 3 "llm_client" --glob="*.py" | grep -v "std_llm_client"

echo -e "\nChecking where std_llm_client is used:"
rg -A 3 "std_llm_client" --glob="*.py"

echo -e "\nChecking OpenaiLLMApi implementation:"
cat edenai_apis/apis/openai/openai_llm_api.py || echo "File not found"

Length of output: 38110


Clarify the Distinction Between llm_client and std_llm_client

The verification confirms that the code intentionally instantiates two separate LLM client instances. In edenai_apis/apis/openai/openai_api.py, llm_client (an instance of LLMEngine) is maintained for certain provider-specific operations, while std_llm_client (an instance of StdLLMEngine) is used for standardized completion calls, as seen in the OpenaiLLMApi implementation and other API modules. Although their coexistence is deliberate and consistent across the codebase, it would help future maintainability if you add inline documentation to clarify the distinct use cases and roles of each client.

edenai_apis/apis/google/info.json (1)

1401-1405: Addition of LLM chat support for Google API.

Good addition of the new LLM chat section to the Google API configuration. This properly aligns with the PR objective of making Eden AI chat API compatible with OpenAI by adding necessary provider configurations.

edenai_apis/apis/openai/openai_llm_api.py (3)

9-10: Good implementation of the LlmInterface.

The OpenaiLLMApi class correctly implements the LlmInterface, which aligns with the PR's goal of standardizing chat API compatibility.


52-86: Clean implementation of OpenAI compatibility.

The implementation properly passes all parameters to the underlying std_llm_client.completion method, maintaining compatibility with the OpenAI API parameters.


1-7:

✅ Verification successful

Clean up unused imports.

There are several imports that aren't being used in this file.

-from typing import Dict, List, Type, Union, Optional
+from typing import List, Type, Union, Optional
-import httpx
+import httpx
-from openai import BaseModel, OpenAI
+from openai import BaseModel
-from openai import NOT_GIVEN
 from features.llm.llm_interface import LlmInterface
 from edenai_apis.features.llm.chat.chat_dataclass import ChatCompletionResponse

🏁 Script executed:

#!/bin/bash
# Check if these imports are used elsewhere in the file
rg "Dict\(" edenai_apis/apis/openai/openai_llm_api.py
rg "OpenAI\(" edenai_apis/apis/openai/openai_llm_api.py
rg "NOT_GIVEN" edenai_apis/apis/openai/openai_llm_api.py

Length of output: 199


Action Required: Cleanup Unused Imports in edenai_apis/apis/openai/openai_llm_api.py

Based on the grep results:

  • There’s no usage of Dict beyond its import.
  • There’s no usage of OpenAI (checked via rg 'OpenAI\(').
  • The only occurrence of NOT_GIVEN is in its import line, with no evidence of being used elsewhere.

Please remove these unused imports as suggested in the diff below:

- from typing import Dict, List, Type, Union, Optional
+ from typing import List, Type, Union, Optional
- import httpx
+ import httpx
- from openai import BaseModel, OpenAI
+ from openai import BaseModel
- from openai import NOT_GIVEN
🧰 Tools
🪛 Ruff (0.8.2)

1-1: typing.Dict imported but unused

Remove unused import: typing.Dict

(F401)


3-3: openai.OpenAI imported but unused

Remove unused import: openai.OpenAI

(F401)


4-4: openai.NOT_GIVEN imported but unused

Remove unused import: openai.NOT_GIVEN

(F401)

edenai_apis/apis/google/google_api.py (3)

19-20: Good addition of LLM engine imports.

The imports added here support the integration of the LLM functionality into the Google API class.


32-32: Proper interface implementation.

Adding the LlmInterface to the GoogleApi class inheritance is the correct approach to implement chat functionality.


60-64:

✅ Verification successful

Proper StdLLMEngine client initialization.

The implementation correctly initializes the StdLLMEngine with the API key from settings. However, ensure that the Google API supports all the functionality needed by the StdLLMEngine.


🏁 Script executed:

#!/bin/bash
# Check if the Google API has a llm__chat implementation to match the interface
rg "def llm__chat" edenai_apis/apis/google/

Length of output: 106


StdLLMEngine client initialization confirmed.

  • The engine is correctly initialized with the API key from settings.
  • Verification shows that the Google API implements the llm__chat method (located in edenai_apis/apis/google/google_llm_api.py), satisfying a key part of the required StdLLMEngine interface.

Please ensure that any additional StdLLMEngine functionalities beyond llm__chat are also supported by the Google API.

edenai_apis/llmengine/llm_engine.py (1)

735-740: LGTM: Provider mapping expansion allows for Amazon integration

The addition of "bedrock_converse" and "amazon" mappings to "bedrock" enables the OpenAI compatibility for Amazon services as described in the PR objectives.

edenai_apis/apis/xai/xai_api.py (4)

5-5: LGTM: Import of XAiLLMApi supports new LLM chat functionality

This import enables the XAiApi class to inherit from XAiLLMApi and gain the LLM chat capabilities.


9-9: LGTM: Added import for StdLLMEngine

The StdLLMEngine import supports the instantiation of the client in the constructor.


13-13: LGTM: Updated class inheritance to include XAiLLMApi

The XAiApi class now inherits from XAiLLMApi, gaining all the LLM chat capabilities.


26-26: Document the purpose of having two different LLM clients

The class now initializes both llm_client (LLMEngine) and std_llm_client (StdLLMEngine). It's not immediately clear why both are needed or how they differ in usage.

Consider adding a comment explaining the purpose and use case for each client:

self.llm_client = LLMEngine(
    provider_name=self.provider_name, provider_config={"api_key": self.api_key}
)

+# StdLLMEngine is used for OpenAI-compatible chat API calls
self.std_llm_client = StdLLMEngine(provider_config={"api_key": self.api_key})
edenai_apis/apis/cohere/cohere_api.py (8)

2-2: Imports look fine.
No issues detected with adding Literal and other typing utilities.


4-4: Importing httpx is appropriate.
Usage is consistent for potential timeout arguments in LLM completions.


5-5: BaseModel import acknowledged.
This is used for type hints on the response_format parameter.


25-25: StdLLMEngine import recognized.
This enables standardized LLM engine usage for coherent chat features.


31-31: Implementing LlmInterface.
Good step to unify the Cohere API with the new LLM interface.


32-32: Importing ChatCompletionResponse.
Implementation for structured return values is consistent.


35-35: Class signature update looks good.
Extending the LlmInterface for chat-based functionalities is appropriate.


54-54: Instantiating StdLLMEngine.
This helps unify chat completions with consistent engine behavior.

edenai_apis/apis/anthropic/anthropic_api.py (1)

1-1: General imports, class signature, and new client setup look fine.
No immediate concerns with these additions or updates, as they enable the LlmInterface and standard engine usage.

Also applies to: 3-3, 4-4, 21-21, 25-25, 26-26, 29-29, 44-44

edenai_apis/apis/meta/meta_api.py (4)

1-1: No issues with added type imports.
These imports are appropriate and useful for the revised type annotations.


20-20: Imports for LLM engines look correct.
Leveraging both LLMEngine and StdLLMEngine is consistent with the new LLM architecture.


24-25: LGTM for LlmInterface and ChatCompletionResponse imports.
These imports align with the newly introduced LLM functionality.


28-28: Adopting LlmInterface is consistent with the overall design.
Inheriting from LlmInterface allows MetaApi to expose standardized LLM chat features.

edenai_apis/apis/mistral/mistral_api.py (4)

1-3: New imports for LLM usage are valid.
These additions provide the types and modules required for the LLM chat interface.


21-23: LLM engine imports align with the updated chat features.
Direct usage of LLMEngine and StdLLMEngine, plus ChatCompletionResponse, is appropriate.


26-26: LlmInterface inheritance is appropriate.
Expanding MistralApi to include LLM features is consistent with the broader initiative.


40-40: Initialization of std_llm_client is clear but consider key validation.
A brief check for missing/invalid keys could preempt runtime errors.

edenai_apis/apis/replicate/replicate_api.py (5)

4-4: Extending typing imports is correct.
The inclusion of additional types ensures robust type checking for the updates.


6-7: Imports for httpx and BaseModel look fine.
These additions power the new LLM chat functionality.


24-26: LlmInterface and ChatCompletionResponse use is consistent.
No concerns with these imports for LLM integrations.


30-32: Extending ReplicateApi to LlmInterface is a good approach.
This looks coherent with the multi-provider LLM design.


51-51: std_llm_client initialization is straightforward.
Consider verifying the API key’s validity to prevent runtime errors.

edenai_apis/features/llm/chat/chat_dataclass.py (3)

6-11: Enum Roles Look Good

The enumeration of roles is concise and clear, providing a solid foundation for role-based messaging.


62-125: Review interplay between temperature and top_p

While both parameters can be used together, some LLM best practices advise using one or the other to avoid unpredictable sampling. Consider adding guidance or a mild validation rule clarifying recommended usage.


198-210: Overall Data Model Implementation Appears Solid

The comprehensive response structure is well-defined and covers key usage metrics, model info, and completion choices. No major issues found. Great job!

Comment on lines +1 to +21
def chat_arguments(provider_name: str):
return {
"model": "mistral/mistral-saba-latest",
"messages": [
{"role": "system", "content": "Always reply like a pirate"},
{
"role": "user",
"content": [
{"type": "text", "text": "Describe this image please!"},
{
"type": "image_url",
"image_url": {
"url": "https://upload.wikimedia.org/wikipedia/commons/thumb/d/dd/Gfp-wisconsin-madison-the-nature-boardwalk.jpg/2560px-Gfp-wisconsin-madison-the-nature-boardwalk.jpg"
},
},
],
},
],
"temperature": 1,
"max_tokens": 1000,
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Address the unused parameter and add documentation.

The function takes a provider_name parameter but doesn't use it in the function body. Also, the function lacks a docstring explaining its purpose and usage.

-def chat_arguments(provider_name: str):
+def chat_arguments(provider_name: str = None):
+    """
+    Provides sample arguments for LLM chat API calls.
+    
+    This function returns a dictionary with standardized parameters for testing or 
+    demonstrating the LLM chat functionality. It includes a sample model, messages,
+    and other configuration values.
+    
+    Args:
+        provider_name (str, optional): The name of the provider. Currently not used,
+                                     but may be used in future to customize arguments
+                                     based on provider capabilities.
+    
+    Returns:
+        dict: Dictionary with chat arguments formatted for the LLM chat API.
+    """
     return {
         "model": "mistral/mistral-saba-latest",
         "messages": [
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
def chat_arguments(provider_name: str):
return {
"model": "mistral/mistral-saba-latest",
"messages": [
{"role": "system", "content": "Always reply like a pirate"},
{
"role": "user",
"content": [
{"type": "text", "text": "Describe this image please!"},
{
"type": "image_url",
"image_url": {
"url": "https://upload.wikimedia.org/wikipedia/commons/thumb/d/dd/Gfp-wisconsin-madison-the-nature-boardwalk.jpg/2560px-Gfp-wisconsin-madison-the-nature-boardwalk.jpg"
},
},
],
},
],
"temperature": 1,
"max_tokens": 1000,
}
def chat_arguments(provider_name: str = None):
"""
Provides sample arguments for LLM chat API calls.
This function returns a dictionary with standardized parameters for testing or
demonstrating the LLM chat functionality. It includes a sample model, messages,
and other configuration values.
Args:
provider_name (str, optional): The name of the provider. Currently not used,
but may be used in future to customize arguments
based on provider capabilities.
Returns:
dict: Dictionary with chat arguments formatted for the LLM chat API.
"""
return {
"model": "mistral/mistral-saba-latest",
"messages": [
{"role": "system", "content": "Always reply like a pirate"},
{
"role": "user",
"content": [
{"type": "text", "text": "Describe this image please!"},
{
"type": "image_url",
"image_url": {
"url": "https://upload.wikimedia.org/wikipedia/commons/thumb/d/dd/Gfp-wisconsin-madison-the-nature-boardwalk.jpg/2560px-Gfp-wisconsin-madison-the-nature-boardwalk.jpg"
},
},
],
},
],
"temperature": 1,
"max_tokens": 1000,
}

Comment on lines 11 to 51
def llm__chat(
self,
messages: List = [],
model: Optional[str] = None,
# Optional OpenAI params: see https://platform.openai.com/docs/api-reference/chat/create
timeout: Optional[Union[float, str, httpx.Timeout]] = None,
temperature: Optional[float] = None,
top_p: Optional[float] = None,
n: Optional[int] = None,
stream: Optional[bool] = None,
stream_options: Optional[dict] = None,
stop: Optional[str] = None,
stop_sequences: Optional[any] = None,
max_tokens: Optional[int] = None,
presence_penalty: Optional[float] = None,
frequency_penalty: Optional[float] = None,
logit_bias: Optional[dict] = None,
# openai v1.0+ new params
response_format: Optional[
Union[dict, Type[BaseModel]]
] = None, # Structured outputs
seed: Optional[int] = None,
tools: Optional[List] = None,
tool_choice: Optional[Union[str, dict]] = None,
logprobs: Optional[bool] = None,
top_logprobs: Optional[int] = None,
parallel_tool_calls: Optional[bool] = None,
deployment_id=None,
extra_headers: Optional[dict] = None,
# soon to be deprecated params by OpenAI -> This should be replaced by tools
functions: Optional[List] = None,
function_call: Optional[str] = None,
base_url: Optional[str] = None,
api_version: Optional[str] = None,
api_key: Optional[str] = None,
model_list: Optional[list] = None, # pass in a list of api_base,keys, etc.
drop_invalid_params: bool = True, # If true, all the invalid parameters will be ignored (dropped) before sending to the model
user: str | None = None,
# Optional parameters
**kwargs,
) -> ChatCompletionResponse:
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Fix mutable default argument and consider type annotation improvements.

The function uses a mutable default argument list for messages, which is a common Python pitfall.

-    def llm__chat(
-        self,
-        messages: List = [],
+    def llm__chat(
+        self,
+        messages: List[dict] = None,

Also, consider being more specific with the type annotation for messages since it's expected to contain chat message objects.

Then initialize the list inside the function:

def llm__chat(self, messages: List[dict] = None, ...):
    if messages is None:
        messages = []
    # rest of function
🧰 Tools
🪛 Ruff (0.8.2)

13-13: Do not use mutable data structures for argument defaults

Replace with None; initialize within function

(B006)


def llm__chat(
self,
messages: List = [],
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Fix mutable default argument risk

Using mutable objects like empty lists as default arguments can lead to unexpected behavior when the function is called multiple times. The default value is created once at function definition time and reused for all calls.

Update the method signature to use None instead of an empty list and initialize it within the function:

-    def llm__chat(
-        self,
-        messages: List = [],
+    def llm__chat(
+        self,
+        messages: Optional[List] = None,

Then add this check at the beginning of the method:

if messages is None:
    messages = []
🧰 Tools
🪛 Ruff (0.8.2)

13-13: Do not use mutable data structures for argument defaults

Replace with None; initialize within function

(B006)


def llm__chat(
self,
messages: List = [],
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Fix mutable default argument risk

Using mutable objects like empty lists as default arguments can lead to unexpected behavior when the function is called multiple times. The default value is created once at function definition time and reused for all calls.

Update the method signature to use None instead of an empty list and initialize it within the function:

-    def llm__chat(
-        self,
-        messages: List = [],
+    def llm__chat(
+        self,
+        messages: Optional[List] = None,

Then add this check at the beginning of the method:

if messages is None:
    messages = []
🧰 Tools
🪛 Ruff (0.8.2)

13-13: Do not use mutable data structures for argument defaults

Replace with None; initialize within function

(B006)

@abstractmethod
def llm__chat(
self,
messages: List = [],
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Avoid mutable default argument for messages.

Using a mutable list as a default argument can lead to unexpected behavior. Replace it with None and initialize within the function body.

-def llm__chat(
-    self,
-    messages: List = [],
-    ...
+def llm__chat(
+    self,
+    messages: Optional[List] = None,
+    ...
):
+    if messages is None:
+        messages = []
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
messages: List = [],
def llm__chat(
self,
messages: Optional[List] = None,
...):
if messages is None:
messages = []
# rest of the function code
🧰 Tools
🪛 Ruff (0.8.2)

15-15: Do not use mutable data structures for argument defaults

Replace with None; initialize within function

(B006)


def llm__chat(
self,
messages: List = [],
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Replace mutable default argument for messages.

Same reasoning as in the other files: avoid potential side effects by setting this to None.

-def llm__chat(
-    self,
-    messages: List = [],
-    ...
+def llm__chat(
+    self,
+    messages: Optional[List] = None,
+    ...
):
+    if messages is None:
+        messages = []
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
messages: List = [],
def llm__chat(
self,
messages: Optional[List] = None,
...
):
if messages is None:
messages = []
# rest of the function implementation
🧰 Tools
🪛 Ruff (0.8.2)

64-64: Do not use mutable data structures for argument defaults

Replace with None; initialize within function

(B006)

Comment on lines 334 to 409
def llm__chat(
self,
messages: List = [],
model: Optional[str] = None,
# Optional OpenAI params: see https://platform.openai.com/docs/api-reference/chat/create
timeout: Optional[Union[float, str, httpx.Timeout]] = None,
temperature: Optional[float] = None,
top_p: Optional[float] = None,
n: Optional[int] = None,
stream: Optional[bool] = None,
stream_options: Optional[dict] = None,
stop: Optional[str] = None,
stop_sequences: Optional[any] = None,
max_tokens: Optional[int] = None,
presence_penalty: Optional[float] = None,
frequency_penalty: Optional[float] = None,
logit_bias: Optional[dict] = None,
# openai v1.0+ new params
response_format: Optional[
Union[dict, Type[BaseModel]]
] = None, # Structured outputs
seed: Optional[int] = None,
tools: Optional[List] = None,
tool_choice: Optional[Union[str, dict]] = None,
logprobs: Optional[bool] = None,
top_logprobs: Optional[int] = None,
parallel_tool_calls: Optional[bool] = None,
deployment_id=None,
extra_headers: Optional[dict] = None,
# soon to be deprecated params by OpenAI -> This should be replaced by tools
functions: Optional[List] = None,
function_call: Optional[str] = None,
base_url: Optional[str] = None,
api_version: Optional[str] = None,
api_key: Optional[str] = None,
model_list: Optional[list] = None, # pass in a list of api_base,keys, etc.
drop_invalid_params: bool = True, # If true, all the invalid parameters will be ignored (dropped) before sending to the model
user: str | None = None,
# Optional parameters
**kwargs,
) -> ChatCompletionResponse:
response = self.std_llm_client.completion(
messages=messages,
model=model,
timeout=timeout,
temperature=temperature,
top_p=top_p,
n=n,
stream=stream,
stream_options=stream_options,
stop=stop,
stop_sequences=stop_sequences,
max_tokens=max_tokens,
presence_penalty=presence_penalty,
frequency_penalty=frequency_penalty,
logit_bias=logit_bias,
response_format=response_format,
seed=seed,
tools=tools,
tool_choice=tool_choice,
logprobs=logprobs,
top_logprobs=top_logprobs,
parallel_tool_calls=parallel_tool_calls,
deployment_id=deployment_id,
extra_headers=extra_headers,
functions=functions,
function_call=function_call,
base_url=base_url,
api_version=api_version,
api_key=api_key,
model_list=model_list,
drop_invalid_params=drop_invalid_params,
user=user,
**kwargs,
)
return response
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Avoid mutable default arguments.

The parameter messages: List = [] at line 336 may lead to unintended behavior if it gets mutated. Adhere to best practices by using None instead, then initializing within the function body.

Proposed fix:

-def llm__chat(self,
-    messages: List = [],
-    ...
-):
+def llm__chat(self,
+    messages: Optional[List] = None,
+    ...
+):
+    if messages is None:
+        messages = []
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
def llm__chat(
self,
messages: List = [],
model: Optional[str] = None,
# Optional OpenAI params: see https://platform.openai.com/docs/api-reference/chat/create
timeout: Optional[Union[float, str, httpx.Timeout]] = None,
temperature: Optional[float] = None,
top_p: Optional[float] = None,
n: Optional[int] = None,
stream: Optional[bool] = None,
stream_options: Optional[dict] = None,
stop: Optional[str] = None,
stop_sequences: Optional[any] = None,
max_tokens: Optional[int] = None,
presence_penalty: Optional[float] = None,
frequency_penalty: Optional[float] = None,
logit_bias: Optional[dict] = None,
# openai v1.0+ new params
response_format: Optional[
Union[dict, Type[BaseModel]]
] = None, # Structured outputs
seed: Optional[int] = None,
tools: Optional[List] = None,
tool_choice: Optional[Union[str, dict]] = None,
logprobs: Optional[bool] = None,
top_logprobs: Optional[int] = None,
parallel_tool_calls: Optional[bool] = None,
deployment_id=None,
extra_headers: Optional[dict] = None,
# soon to be deprecated params by OpenAI -> This should be replaced by tools
functions: Optional[List] = None,
function_call: Optional[str] = None,
base_url: Optional[str] = None,
api_version: Optional[str] = None,
api_key: Optional[str] = None,
model_list: Optional[list] = None, # pass in a list of api_base,keys, etc.
drop_invalid_params: bool = True, # If true, all the invalid parameters will be ignored (dropped) before sending to the model
user: str | None = None,
# Optional parameters
**kwargs,
) -> ChatCompletionResponse:
response = self.std_llm_client.completion(
messages=messages,
model=model,
timeout=timeout,
temperature=temperature,
top_p=top_p,
n=n,
stream=stream,
stream_options=stream_options,
stop=stop,
stop_sequences=stop_sequences,
max_tokens=max_tokens,
presence_penalty=presence_penalty,
frequency_penalty=frequency_penalty,
logit_bias=logit_bias,
response_format=response_format,
seed=seed,
tools=tools,
tool_choice=tool_choice,
logprobs=logprobs,
top_logprobs=top_logprobs,
parallel_tool_calls=parallel_tool_calls,
deployment_id=deployment_id,
extra_headers=extra_headers,
functions=functions,
function_call=function_call,
base_url=base_url,
api_version=api_version,
api_key=api_key,
model_list=model_list,
drop_invalid_params=drop_invalid_params,
user=user,
**kwargs,
)
return response
def llm__chat(
self,
messages: Optional[List] = None,
model: Optional[str] = None,
# Optional OpenAI params: see https://platform.openai.com/docs/api-reference/chat/create
timeout: Optional[Union[float, str, httpx.Timeout]] = None,
temperature: Optional[float] = None,
top_p: Optional[float] = None,
n: Optional[int] = None,
stream: Optional[bool] = None,
stream_options: Optional[dict] = None,
stop: Optional[str] = None,
stop_sequences: Optional[any] = None,
max_tokens: Optional[int] = None,
presence_penalty: Optional[float] = None,
frequency_penalty: Optional[float] = None,
logit_bias: Optional[dict] = None,
# openai v1.0+ new params
response_format: Optional[
Union[dict, Type[BaseModel]]
] = None, # Structured outputs
seed: Optional[int] = None,
tools: Optional[List] = None,
tool_choice: Optional[Union[str, dict]] = None,
logprobs: Optional[bool] = None,
top_logprobs: Optional[int] = None,
parallel_tool_calls: Optional[bool] = None,
deployment_id=None,
extra_headers: Optional[dict] = None,
# soon to be deprecated params by OpenAI -> This should be replaced by tools
functions: Optional[List] = None,
function_call: Optional[str] = None,
base_url: Optional[str] = None,
api_version: Optional[str] = None,
api_key: Optional[str] = None,
model_list: Optional[list] = None, # pass in a list of api_base,keys, etc.
drop_invalid_params: bool = True, # If true, all the invalid parameters will be ignored (dropped) before sending to the model
user: str | None = None,
# Optional parameters
**kwargs,
) -> ChatCompletionResponse:
if messages is None:
messages = []
response = self.std_llm_client.completion(
messages=messages,
model=model,
timeout=timeout,
temperature=temperature,
top_p=top_p,
n=n,
stream=stream,
stream_options=stream_options,
stop=stop,
stop_sequences=stop_sequences,
max_tokens=max_tokens,
presence_penalty=presence_penalty,
frequency_penalty=frequency_penalty,
logit_bias=logit_bias,
response_format=response_format,
seed=seed,
tools=tools,
tool_choice=tool_choice,
logprobs=logprobs,
top_logprobs=top_logprobs,
parallel_tool_calls=parallel_tool_calls,
deployment_id=deployment_id,
extra_headers=extra_headers,
functions=functions,
function_call=function_call,
base_url=base_url,
api_version=api_version,
api_key=api_key,
model_list=model_list,
drop_invalid_params=drop_invalid_params,
user=user,
**kwargs,
)
return response
🧰 Tools
🪛 Ruff (0.8.2)

336-336: Do not use mutable data structures for argument defaults

Replace with None; initialize within function

(B006)


def llm__chat(
self,
messages: List = [],
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Avoid mutable default for messages.

Likewise, using a list as a default can cause shared state across calls. Use None and initialize within the function.

-def llm__chat(self,
-    messages: List = [],
-    ...
-):
+def llm__chat(self,
+    messages: Optional[List] = None,
+    ...
+):
+    if messages is None:
+        messages = []
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
messages: List = [],
def llm__chat(self,
messages: Optional[List] = None,
...
):
if messages is None:
messages = []
# Rest of the function implementation
🧰 Tools
🪛 Ruff (0.8.2)

38-38: Do not use mutable data structures for argument defaults

Replace with None; initialize within function

(B006)


class AmazonLLMApi(LlmInterface):

def __init__(self, api_keys: Dict = {}) -> None:
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Avoid mutable default for api_keys.

Using {} as a default can lead to inadvertent shared usage. Prefer None and initialize inside the constructor.

-def __init__(self, api_keys: Dict = {}):
+def __init__(self, api_keys: Optional[Dict] = None):
+    if api_keys is None:
+        api_keys = {}

Committable suggestion skipped: line range outside the PR's diff.

🧰 Tools
🪛 Ruff (0.8.2)

22-22: Do not use mutable data structures for argument defaults

Replace with None; initialize within function

(B006)

Comment on lines 134 to 209
def llm__chat(
self,
messages: List = [],
model: Optional[str] = None,
# Optional OpenAI params: see https://platform.openai.com/docs/api-reference/chat/create
timeout: Optional[Union[float, str, httpx.Timeout]] = None,
temperature: Optional[float] = None,
top_p: Optional[float] = None,
n: Optional[int] = None,
stream: Optional[bool] = None,
stream_options: Optional[dict] = None,
stop: Optional[str] = None,
stop_sequences: Optional[any] = None,
max_tokens: Optional[int] = None,
presence_penalty: Optional[float] = None,
frequency_penalty: Optional[float] = None,
logit_bias: Optional[dict] = None,
# openai v1.0+ new params
response_format: Optional[
Union[dict, Type[BaseModel]]
] = None, # Structured outputs
seed: Optional[int] = None,
tools: Optional[List] = None,
tool_choice: Optional[Union[str, dict]] = None,
logprobs: Optional[bool] = None,
top_logprobs: Optional[int] = None,
parallel_tool_calls: Optional[bool] = None,
deployment_id=None,
extra_headers: Optional[dict] = None,
# soon to be deprecated params by OpenAI -> This should be replaced by tools
functions: Optional[List] = None,
function_call: Optional[str] = None,
base_url: Optional[str] = None,
api_version: Optional[str] = None,
api_key: Optional[str] = None,
model_list: Optional[list] = None, # pass in a list of api_base,keys, etc.
drop_invalid_params: bool = True, # If true, all the invalid parameters will be ignored (dropped) before sending to the model
user: str | None = None,
# Optional parameters
**kwargs,
) -> ChatCompletionResponse:
response = self.std_llm_client.completion(
messages=messages,
model=model,
timeout=timeout,
temperature=temperature,
top_p=top_p,
n=n,
stream=stream,
stream_options=stream_options,
stop=stop,
stop_sequences=stop_sequences,
max_tokens=max_tokens,
presence_penalty=presence_penalty,
frequency_penalty=frequency_penalty,
logit_bias=logit_bias,
response_format=response_format,
seed=seed,
tools=tools,
tool_choice=tool_choice,
logprobs=logprobs,
top_logprobs=top_logprobs,
parallel_tool_calls=parallel_tool_calls,
deployment_id=deployment_id,
extra_headers=extra_headers,
functions=functions,
function_call=function_call,
base_url=base_url,
api_version=api_version,
api_key=api_key,
model_list=model_list,
drop_invalid_params=drop_invalid_params,
user=user,
**kwargs,
)
return response
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Avoid mutable default arguments & ensure robust parameter handling.
Using messages: List = [] can lead to unexpected behavior. Replace with None default and initialize inside the function.

Proposed fix:

- def llm__chat(
-     self,
-     messages: List = [],
+ def llm__chat(
+     self,
+     messages: Optional[List] = None,
      ...
):
+     if messages is None:
+         messages = []
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
def llm__chat(
self,
messages: List = [],
model: Optional[str] = None,
# Optional OpenAI params: see https://platform.openai.com/docs/api-reference/chat/create
timeout: Optional[Union[float, str, httpx.Timeout]] = None,
temperature: Optional[float] = None,
top_p: Optional[float] = None,
n: Optional[int] = None,
stream: Optional[bool] = None,
stream_options: Optional[dict] = None,
stop: Optional[str] = None,
stop_sequences: Optional[any] = None,
max_tokens: Optional[int] = None,
presence_penalty: Optional[float] = None,
frequency_penalty: Optional[float] = None,
logit_bias: Optional[dict] = None,
# openai v1.0+ new params
response_format: Optional[
Union[dict, Type[BaseModel]]
] = None, # Structured outputs
seed: Optional[int] = None,
tools: Optional[List] = None,
tool_choice: Optional[Union[str, dict]] = None,
logprobs: Optional[bool] = None,
top_logprobs: Optional[int] = None,
parallel_tool_calls: Optional[bool] = None,
deployment_id=None,
extra_headers: Optional[dict] = None,
# soon to be deprecated params by OpenAI -> This should be replaced by tools
functions: Optional[List] = None,
function_call: Optional[str] = None,
base_url: Optional[str] = None,
api_version: Optional[str] = None,
api_key: Optional[str] = None,
model_list: Optional[list] = None, # pass in a list of api_base,keys, etc.
drop_invalid_params: bool = True, # If true, all the invalid parameters will be ignored (dropped) before sending to the model
user: str | None = None,
# Optional parameters
**kwargs,
) -> ChatCompletionResponse:
response = self.std_llm_client.completion(
messages=messages,
model=model,
timeout=timeout,
temperature=temperature,
top_p=top_p,
n=n,
stream=stream,
stream_options=stream_options,
stop=stop,
stop_sequences=stop_sequences,
max_tokens=max_tokens,
presence_penalty=presence_penalty,
frequency_penalty=frequency_penalty,
logit_bias=logit_bias,
response_format=response_format,
seed=seed,
tools=tools,
tool_choice=tool_choice,
logprobs=logprobs,
top_logprobs=top_logprobs,
parallel_tool_calls=parallel_tool_calls,
deployment_id=deployment_id,
extra_headers=extra_headers,
functions=functions,
function_call=function_call,
base_url=base_url,
api_version=api_version,
api_key=api_key,
model_list=model_list,
drop_invalid_params=drop_invalid_params,
user=user,
**kwargs,
)
return response
def llm__chat(
self,
messages: Optional[List] = None,
model: Optional[str] = None,
# Optional OpenAI params: see https://platform.openai.com/docs/api-reference/chat/create
timeout: Optional[Union[float, str, httpx.Timeout]] = None,
temperature: Optional[float] = None,
top_p: Optional[float] = None,
n: Optional[int] = None,
stream: Optional[bool] = None,
stream_options: Optional[dict] = None,
stop: Optional[str] = None,
stop_sequences: Optional[any] = None,
max_tokens: Optional[int] = None,
presence_penalty: Optional[float] = None,
frequency_penalty: Optional[float] = None,
logit_bias: Optional[dict] = None,
# openai v1.0+ new params
response_format: Optional[
Union[dict, Type[BaseModel]]
] = None, # Structured outputs
seed: Optional[int] = None,
tools: Optional[List] = None,
tool_choice: Optional[Union[str, dict]] = None,
logprobs: Optional[bool] = None,
top_logprobs: Optional[int] = None,
parallel_tool_calls: Optional[bool] = None,
deployment_id=None,
extra_headers: Optional[dict] = None,
# soon to be deprecated params by OpenAI -> This should be replaced by tools
functions: Optional[List] = None,
function_call: Optional[str] = None,
base_url: Optional[str] = None,
api_version: Optional[str] = None,
api_key: Optional[str] = None,
model_list: Optional[list] = None, # pass in a list of api_base,keys, etc.
drop_invalid_params: bool = True, # If true, all the invalid parameters will be ignored (dropped) before sending to the model
user: str | None = None,
# Optional parameters
**kwargs,
) -> ChatCompletionResponse:
if messages is None:
messages = []
response = self.std_llm_client.completion(
messages=messages,
model=model,
timeout=timeout,
temperature=temperature,
top_p=top_p,
n=n,
stream=stream,
stream_options=stream_options,
stop=stop,
stop_sequences=stop_sequences,
max_tokens=max_tokens,
presence_penalty=presence_penalty,
frequency_penalty=frequency_penalty,
logit_bias=logit_bias,
response_format=response_format,
seed=seed,
tools=tools,
tool_choice=tool_choice,
logprobs=logprobs,
top_logprobs=top_logprobs,
parallel_tool_calls=parallel_tool_calls,
deployment_id=deployment_id,
extra_headers=extra_headers,
functions=functions,
function_call=function_call,
base_url=base_url,
api_version=api_version,
api_key=api_key,
model_list=model_list,
drop_invalid_params=drop_invalid_params,
user=user,
**kwargs,
)
return response
🧰 Tools
🪛 Ruff (0.8.2)

136-136: Do not use mutable data structures for argument defaults

Replace with None; initialize within function

(B006)

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 5

🔭 Outside diff range comments (1)
edenai_apis/llmengine/tests/test_tools.py (1)

31-75: ⚠️ Potential issue

Duplicate test method names will cause test execution issues.

There are two methods with the exact same name test_tool_type_instantiation (lines 31 and 76). This will cause only one of them to be executed when running tests, as test frameworks typically use method names to identify individual tests.

Rename the second test method to differentiate it:

-    def test_tool_type_instantiation(self):
+    def test_tool_type_modification(self):

This better reflects what the test is actually doing (testing the modification of a function name).

Also applies to: 76-143

♻️ Duplicate comments (2)
edenai_apis/apis/openai/openai_llm_api.py (1)

11-13: ⚠️ Potential issue

Fix mutable default argument and improve type annotation.

The function uses a mutable default argument list for messages, which is a common Python pitfall. Mutable defaults are created once at function definition time and shared between calls, which can lead to unexpected behavior.

-    def llm__chat(
-        self,
-        messages: List = [],
+    def llm__chat(
+        self,
+        messages: List[dict] = None,

Additionally, you should initialize the list inside the function to avoid the mutable default issue:

if messages is None:
    messages = []
🧰 Tools
🪛 Ruff (0.8.2)

13-13: Do not use mutable data structures for argument defaults

Replace with None; initialize within function

(B006)

edenai_apis/apis/amazon/amazon_llm_api.py (1)

15-15: ⚠️ Potential issue

Fix mutable default argument in constructor.

Using a mutable default value (empty dict) can cause unexpected behavior across class instances.

-    def __init__(self, api_keys: Dict = {}) -> None:
+    def __init__(self, api_keys: Optional[Dict] = None) -> None:
+        if api_keys is None:
+            api_keys = {}
🧰 Tools
🪛 Ruff (0.8.2)

15-15: Do not use mutable data structures for argument defaults

Replace with None; initialize within function

(B006)

🧹 Nitpick comments (26)
edenai_apis/features/ocr/financial_parser/__init__.py (1)

12-13: Clarify the Purpose of the Added Trailing Comma and Unused Import.
You've added a trailing comma after FinancialParserDataClass to improve readability and allow for potential future additions. However, static analysis indicates that FinancialParserDataClass is imported but not used anywhere in the module. If this entity is intended to be part of the module’s public API, consider adding it to an explicit __all__ list. Otherwise, you might remove the import to clean up unused code.

🧰 Tools
🪛 Ruff (0.8.2)

12-12: .financial_parser_dataclass.FinancialParserObjectDataClass imported but unused; consider removing, adding to __all__, or using a redundant alias

(F401)


13-13: .financial_parser_dataclass.FinancialParserDataClass imported but unused; consider removing, adding to __all__, or using a redundant alias

(F401)

edenai_apis/features/ocr/anonymization_async/__init__.py (1)

1-3: Redundant Import Re-addition and Unused Import Notice

The changes merely remove and then re-add the same import statement, resulting in no functional difference. Also, according to static analysis, AnonymizationAsyncDataClass is imported but not used in this file. If the purpose is to re-export it as part of the module's public API, consider adding an __all__ declaration (e.g., __all__ = ["anonymization_async_arguments", "AnonymizationAsyncDataClass"]). Otherwise, you may remove the unused import to clean up the code.

🧰 Tools
🪛 Ruff (0.8.2)

1-1: .anonymization_async_args.anonymization_async_arguments imported but unused; consider removing, adding to __all__, or using a redundant alias

(F401)


2-2: .anonymization_async_dataclass.AnonymizationAsyncDataClass imported but unused; consider removing, adding to __all__, or using a redundant alias

(F401)

edenai_apis/llmengine/tests/test_tools.py (1)

12-19: Use proper exception handling in the factorial function.

The factorial function is currently raising string literals instead of proper exception objects, which is not a Python best practice.

-        raise "Cannot do more than 10 in this test case"
+        raise ValueError("Cannot do more than 10 in this test case")

-        raise "Cannot do negative numbers"
+        raise ValueError("Cannot do negative numbers")
🧰 Tools
🪛 Ruff (0.8.2)

14-14: Cannot raise a literal. Did you intend to return it or raise an Exception?

(B016)


16-16: Cannot raise a literal. Did you intend to return it or raise an Exception?

(B016)

edenai_apis/features/text/plagia_detection/__init__.py (1)

1-7: Minor Syntax and API Export Clarity Update.
The added trailing comma after PlagiaDetectionDataClass is a good stylistic improvement that facilitates future modifications. In addition, to avoid unused import warnings from static analysis tools and to clearly signal your module’s public API, consider explicitly defining an __all__ list. For example, you could add at the top or bottom of this file:

+__all__ = [
+    "plagia_detection_arguments",
+    "PlagiaDetectionCandidate",
+    "PlagiaDetectionItem",
+    "PlagiaDetectionDataClass",
+]
🧰 Tools
🪛 Ruff (0.8.2)

1-1: .plagia_detection_args.plagia_detection_arguments imported but unused; consider removing, adding to __all__, or using a redundant alias

(F401)


3-3: .plagia_detection_dataclass.PlagiaDetectionCandidate imported but unused; consider removing, adding to __all__, or using a redundant alias

(F401)


4-4: .plagia_detection_dataclass.PlagiaDetectionItem imported but unused; consider removing, adding to __all__, or using a redundant alias

(F401)


5-5: .plagia_detection_dataclass.PlagiaDetectionDataClass imported but unused; consider removing, adding to __all__, or using a redundant alias

(F401)

edenai_apis/features/image/explicit_content/pattern.py (1)

1-213: Improved pattern categorization supports OpenAI compatibility.

The expanded categorizations for explicit content detection align with industry-standard content moderation systems, including those used by OpenAI. These enhancements will help ensure compatibility with OpenAI's content policies when integrating with their API, which is a key objective of this PR.

These pattern expansions help establish a comprehensive content moderation system. Consider reviewing OpenAI's latest content moderation categories periodically to ensure continued compatibility, as their policies may evolve over time.

edenai_apis/apis/sightengine/__init__.py (1)

1-2: Review: Unused Import Concern

The file imports SightEngineApi yet does not use it directly. If this module is intended to re-export SightEngineApi for public use, consider adding an explicit __all__ declaration (e.g., __all__ = ["SightEngineApi"]). Otherwise, if it’s not needed here, removing the import would clean up the module.

🧰 Tools
🪛 Ruff (0.8.2)

1-1: .sightengine_api.SightEngineApi imported but unused; consider removing, adding to __all__, or using a redundant alias

(F401)

edenai_apis/apis/astria/__init__.py (1)

1-2: Review: Unused Import Observation

The import of AstriaApi in this file is not referenced anywhere. If the goal is to expose AstriaApi as a public component of the module, please consider adding it to an __all__ list. Alternatively, if it’s not required here, removing it might help minimize clutter.

🧰 Tools
🪛 Ruff (0.8.2)

1-1: .astria_api.AstriaApi imported but unused; consider removing, adding to __all__, or using a redundant alias

(F401)

edenai_apis/apis/jina/__init__.py (1)

1-2: Review: Verify Public API Exposure

The module imports JinaApi but does not use it internally. If the intent is to re-export JinaApi for users of the package, it would be clearer to declare it in an __all__ list (e.g., __all__ = ["JinaApi"]). Otherwise, consider removing the unused import.

🧰 Tools
🪛 Ruff (0.8.2)

1-1: .jina_api.JinaApi imported but unused; consider removing, adding to __all__, or using a redundant alias

(F401)

edenai_apis/apis/leonardo/__init__.py (1)

1-2: Review: Evaluate Import Usage

Here, LeonardoApi is imported but not referenced within the file. If this module is meant to serve as an API surface to expose LeonardoApi, then including an __all__ declaration (e.g., __all__ = ["LeonardoApi"]) can improve clarity. Otherwise, removing the import may be preferable.

🧰 Tools
🪛 Ruff (0.8.2)

1-1: .leonardo_api.LeonardoApi imported but unused; consider removing, adding to __all__, or using a redundant alias

(F401)

edenai_apis/apis/sapling/__init__.py (1)

1-2: Review: Unused Import Strategy

The file imports SaplingApi without any direct use of it. To clarify its purpose, either add it to an __all__ list (for instance, __all__ = ["SaplingApi"]) if it is to be part of the module’s public interface, or remove the import if it serves no purpose here.

🧰 Tools
🪛 Ruff (0.8.2)

1-1: .sapling_api.SaplingApi imported but unused; consider removing, adding to __all__, or using a redundant alias

(F401)

edenai_apis/apis/gladia/__init__.py (1)

1-1: Unused Import: Consider Adding to __all__ for Explicit API Exposure

The GladiaApi is imported on line 1 but not used within this file. If it is intended to be a public part of the module’s API, consider adding it to an __all__ list (e.g., __all__ = ["GladiaApi"]) to both document its intended export and suppress unused import warnings.

🧰 Tools
🪛 Ruff (0.8.2)

1-1: .gladia_api.GladiaApi imported but unused; consider removing, adding to __all__, or using a redundant alias

(F401)

edenai_apis/apis/together_ai/__init__.py (1)

1-1: Public API Clarity: Expose TogetheraiApi via __all__

The import of TogetheraiApi on line 1 is currently not used within this file. To ensure clear documentation of the public API and avoid static analysis warnings, consider defining an __all__ list (e.g., __all__ = ["TogetheraiApi"]) if this class is intended for external use.

🧰 Tools
🪛 Ruff (0.8.2)

1-1: .together_ai_api.TogetheraiApi imported but unused; consider removing, adding to __all__, or using a redundant alias

(F401)

edenai_apis/apis/corticalio/__init__.py (1)

1-1: Clarify Public Exposure of CorticalioApi

The CorticalioApi is imported on line 1 but not utilized within this file. If its purpose is to be part of the public API, consider adding it to an __all__ array (for example, __all__ = ["CorticalioApi"]) to improve clarity and avoid unused import warnings.

🧰 Tools
🪛 Ruff (0.8.2)

1-1: .corticalio_api.CorticalioApi imported but unused; consider removing, adding to __all__, or using a redundant alias

(F401)

edenai_apis/apis/readyredact/__init__.py (1)

1-1: Review Unused Import: Document or Remove ReadyRedactApi

The import of ReadyRedactApi on line 1 is currently unused in this file. If this API is intended for public consumption, it is beneficial to add an __all__ declaration (e.g., __all__ = ["ReadyRedactApi"]) to clearly document its availability. Otherwise, consider removing the import to clean up the code.

🧰 Tools
🪛 Ruff (0.8.2)

1-1: .readyredact_api.ReadyRedactApi imported but unused; consider removing, adding to __all__, or using a redundant alias

(F401)

edenai_apis/apis/perplexityai/__init__.py (1)

1-1: Manage Unused Import: Consider Exporting PerplexityApi

The PerplexityApi is imported on line 1 but not directly used within this file. If the intention is to expose PerplexityApi as part of the package’s public interface, adding it to an __all__ list (e.g., __all__ = ["PerplexityApi"]) can provide clarity and suppress static analysis warnings. If not, removing the import may be preferable.

🧰 Tools
🪛 Ruff (0.8.2)

1-1: .perplexityai_api.PerplexityApi imported but unused; consider removing, adding to __all__, or using a redundant alias

(F401)

edenai_apis/apis/alephalpha/__init__.py (1)

1-1: Unused Import Consideration

The file imports AlephAlphaApi from .alephalpha_api but does not use it explicitly in this module. If the intent is to re-export this class from the package, please consider adding it to an __all__ variable. Otherwise, if it is not intended for external use from this module, you might remove the unused import to satisfy static analysis warnings.

🧰 Tools
🪛 Ruff (0.8.2)

1-1: .alephalpha_api.AlephAlphaApi imported but unused; consider removing, adding to __all__, or using a redundant alias

(F401)

edenai_apis/apis/senseloaf/__init__.py (1)

1-1: Unused Import Consideration

The import of SenseloafApi from .senseloaf_api is not used within the module. If you intend to make this API accessible as part of the package’s public interface, please add it to an __all__ declaration. Otherwise, consider removing the import to avoid unused code warnings.

🧰 Tools
🪛 Ruff (0.8.2)

1-1: .senseloaf_api.SenseloafApi imported but unused; consider removing, adding to __all__, or using a redundant alias

(F401)

edenai_apis/features/image/embeddings/__init__.py (1)

2-2: Re‑Export Imports Confirmation

The file re‑imports EmbeddingDataClass and EmbeddingsDataClass from .embeddings_dataclass. If these classes are meant to be part of the public interface for this module, ensure that they are included in an __all__ list. If not, consider removing them if they remain unused to clear the static analysis warning.

🧰 Tools
🪛 Ruff (0.8.2)

2-2: .embeddings_dataclass.EmbeddingDataClass imported but unused; consider removing, adding to __all__, or using a redundant alias

(F401)


2-2: .embeddings_dataclass.EmbeddingsDataClass imported but unused; consider removing, adding to __all__, or using a redundant alias

(F401)

edenai_apis/apis/openai/openai_llm_api.py (4)

1-1: Remove unused import.

Import Dict is defined but never used in this file.

-from typing import Dict, List, Type, Union, Optional
+from typing import List, Type, Union, Optional
🧰 Tools
🪛 Ruff (0.8.2)

1-1: typing.Dict imported but unused

Remove unused import: typing.Dict

(F401)


3-4: Remove unused imports.

The imports OpenAI and NOT_GIVEN are defined but never used in this file.

-from openai import BaseModel, OpenAI
-from openai import NOT_GIVEN
+from openai import BaseModel
🧰 Tools
🪛 Ruff (0.8.2)

3-3: openai.OpenAI imported but unused

Remove unused import: openai.OpenAI

(F401)


4-4: openai.NOT_GIVEN imported but unused

Remove unused import: openai.NOT_GIVEN

(F401)


23-23: Use proper type annotation instead of any.

The parameter stop_sequences is using an improper type annotation of any which should be replaced with Any from the typing module.

-        stop_sequences: Optional[any] = None,
+        stop_sequences: Optional[Any] = None,

Note: You'll need to add Any to your imports from the typing module.


38-38: Add type annotation for consistency.

All other parameters have type annotations except for deployment_id. For consistency, consider adding a type hint.

-        deployment_id=None,
+        deployment_id: Optional[str] = None,
edenai_apis/apis/corticalio/tests/test_cortical_client.py (1)

51-52: Unused exception variable.

The variable e in the exception handler is assigned but never used. While this is a common pattern in pytest for testing that an exception is raised, consider either using the variable or omitting the assignment.

-        with pytest.raises(ProviderException) as e:
+        with pytest.raises(ProviderException):
             cortical_client.extract_keywords("", "en")
🧰 Tools
🪛 Ruff (0.8.2)

51-51: Local variable e is assigned to but never used

Remove assignment to unused variable e

(F841)

edenai_apis/apis/base64/base64_helpers.py (1)

126-129: Unused loop control variable.

The variable page_index in the loop is not used within the loop body. Consider using _ to indicate an unused variable.

-    for page_index, page_elements in sorted(page_dict.items()):
+    for _, page_elements in sorted(page_dict.items()):
         new_response.append(page_elements)
🧰 Tools
🪛 Ruff (0.8.2)

126-126: Loop control variable page_index not used within loop body

(B007)

edenai_apis/apis/affinda/tests/test_client.py (2)

45-45: Unused variable in test.

The variable organization is assigned but never used. Since this test function is for checking exception behavior, you can omit the assignment.

-            organization = self.client.get_organization("bad_id__dfkredfmlmdfd")
+            self.client.get_organization("bad_id__dfkredfmlmdfd")
🧰 Tools
🪛 Ruff (0.8.2)

45-45: Local variable organization is assigned to but never used

Remove assignment to unused variable organization

(F841)


125-125: Unused variable in test.

The variable workspace is assigned but never used. Since this test function is for checking exception behavior, you can omit the assignment.

-            workspace = self.client.get_workspace("bad_id__dfkredfmlmdfd")
+            self.client.get_workspace("bad_id__dfkredfmlmdfd")
🧰 Tools
🪛 Ruff (0.8.2)

125-125: Local variable workspace is assigned to but never used

Remove assignment to unused variable workspace

(F841)

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 60c358a and 211c813.

📒 Files selected for processing (137)
  • edenai_apis/__init__.py (1 hunks)
  • edenai_apis/apis/affinda/document.py (12 hunks)
  • edenai_apis/apis/affinda/models.py (1 hunks)
  • edenai_apis/apis/affinda/standardization.py (1 hunks)
  • edenai_apis/apis/affinda/tests/test_client.py (5 hunks)
  • edenai_apis/apis/ai21labs/errors.py (1 hunks)
  • edenai_apis/apis/alephalpha/__init__.py (1 hunks)
  • edenai_apis/apis/amazon/amazon_api.py (2 hunks)
  • edenai_apis/apis/amazon/amazon_llm_api.py (1 hunks)
  • edenai_apis/apis/amazon/config.py (2 hunks)
  • edenai_apis/apis/anthropic/anthropic_api.py (4 hunks)
  • edenai_apis/apis/anthropic/errors.py (1 hunks)
  • edenai_apis/apis/astria/__init__.py (1 hunks)
  • edenai_apis/apis/base64/base64_helpers.py (11 hunks)
  • edenai_apis/apis/corticalio/__init__.py (1 hunks)
  • edenai_apis/apis/corticalio/client.py (2 hunks)
  • edenai_apis/apis/corticalio/helpers.py (1 hunks)
  • edenai_apis/apis/corticalio/tests/test_cortical_client.py (2 hunks)
  • edenai_apis/apis/dataleon/dataleon_ocr_normalizer.py (5 hunks)
  • edenai_apis/apis/elevenlabs/errors.py (1 hunks)
  • edenai_apis/apis/faker/faker_api.py (1 hunks)
  • edenai_apis/apis/gladia/__init__.py (1 hunks)
  • edenai_apis/apis/gladia/errors.py (2 hunks)
  • edenai_apis/apis/google/errors.py (1 hunks)
  • edenai_apis/apis/google/google_api.py (3 hunks)
  • edenai_apis/apis/jina/__init__.py (1 hunks)
  • edenai_apis/apis/klippa/klippa_ocr_normalizer.py (9 hunks)
  • edenai_apis/apis/leonardo/__init__.py (1 hunks)
  • edenai_apis/apis/leonardo/config.py (1 hunks)
  • edenai_apis/apis/lovoai/config.py (1 hunks)
  • edenai_apis/apis/meta/errors.py (1 hunks)
  • edenai_apis/apis/meta/meta_api.py (4 hunks)
  • edenai_apis/apis/mindee/mindee_ocr_normalizer.py (4 hunks)
  • edenai_apis/apis/mistral/errors.py (1 hunks)
  • edenai_apis/apis/mistral/mistral_api.py (4 hunks)
  • edenai_apis/apis/openai/openai_llm_api.py (1 hunks)
  • edenai_apis/apis/perplexityai/__init__.py (1 hunks)
  • edenai_apis/apis/privateai/errors.py (1 hunks)
  • edenai_apis/apis/readyredact/__init__.py (1 hunks)
  • edenai_apis/apis/replicate/config.py (1 hunks)
  • edenai_apis/apis/replicate/replicate_api.py (4 hunks)
  • edenai_apis/apis/sapling/__init__.py (1 hunks)
  • edenai_apis/apis/senseloaf/__init__.py (1 hunks)
  • edenai_apis/apis/senseloaf/client.py (1 hunks)
  • edenai_apis/apis/senseloaf/errors.py (1 hunks)
  • edenai_apis/apis/senseloaf/models.py (1 hunks)
  • edenai_apis/apis/senseloaf/remapping.py (6 hunks)
  • edenai_apis/apis/sightengine/__init__.py (1 hunks)
  • edenai_apis/apis/together_ai/__init__.py (1 hunks)
  • edenai_apis/apis/together_ai/errors.py (1 hunks)
  • edenai_apis/apis/together_ai/together_ai_api.py (4 hunks)
  • edenai_apis/apis/twelvelabs/__init__.py (0 hunks)
  • edenai_apis/apis/veryfi/veryfi_ocr_normalizer.py (6 hunks)
  • edenai_apis/apis/writesonic/writesonic_api.py (1 hunks)
  • edenai_apis/features/image/ai_detection/ai_detection_args.py (1 hunks)
  • edenai_apis/features/image/anonymization/anonymization_args.py (1 hunks)
  • edenai_apis/features/image/automl_classification/predict_async/automl_classification_predict_async_args.py (1 hunks)
  • edenai_apis/features/image/automl_classification/upload_data_async/automl_classification_upload_data_async_args.py (0 hunks)
  • edenai_apis/features/image/background_removal/background_removal_args.py (0 hunks)
  • edenai_apis/features/image/embeddings/__init__.py (1 hunks)
  • edenai_apis/features/image/embeddings/embeddings_args.py (0 hunks)
  • edenai_apis/features/image/explicit_content/category.py (1 hunks)
  • edenai_apis/features/image/explicit_content/pattern.py (10 hunks)
  • edenai_apis/features/image/face_compare/face_compare_args.py (0 hunks)
  • edenai_apis/features/image/face_detection/face_detection_args.py (0 hunks)
  • edenai_apis/features/image/face_recognition/add_face/face_recognition_add_face_args.py (0 hunks)
  • edenai_apis/features/image/face_recognition/recognize/face_recognition_recognize_args.py (0 hunks)
  • edenai_apis/features/image/generation_fine_tuning/create_project_async/generation_fine_tuning_create_project_async_args.py (0 hunks)
  • edenai_apis/features/image/landmark_detection/landmark_detection_args.py (0 hunks)
  • edenai_apis/features/image/search/delete_image/search_delete_image_args.py (1 hunks)
  • edenai_apis/features/image/search/get_image/search_get_image_args.py (1 hunks)
  • edenai_apis/features/image/search/get_images/search_get_images_args.py (1 hunks)
  • edenai_apis/features/image/search/launch_similarity/search_launch_similarity_args.py (0 hunks)
  • edenai_apis/features/image/search/upload_image/search_upload_image_args.py (0 hunks)
  • edenai_apis/features/image/variation/variation_dataclass.py (1 hunks)
  • edenai_apis/features/ocr/anonymization_async/__init__.py (1 hunks)
  • edenai_apis/features/ocr/anonymization_async/anonymization_async_args.py (1 hunks)
  • edenai_apis/features/ocr/anonymization_async/anonymization_async_dataclass.py (1 hunks)
  • edenai_apis/features/ocr/bank_check_parsing/bank_check_parsing_args.py (1 hunks)
  • edenai_apis/features/ocr/custom_document_parsing_async/custom_document_parsing_async_args.py (0 hunks)
  • edenai_apis/features/ocr/data_extraction/data_extraction_args.py (1 hunks)
  • edenai_apis/features/ocr/financial_parser/__init__.py (1 hunks)
  • edenai_apis/features/ocr/financial_parser/financial_parser_dataclass.py (1 hunks)
  • edenai_apis/features/ocr/identity_parser/identity_parser_dataclass.py (2 hunks)
  • edenai_apis/features/ocr/invoice_parser/invoice_parser_args.py (0 hunks)
  • edenai_apis/features/ocr/invoice_parser/invoice_parser_dataclass.py (2 hunks)
  • edenai_apis/features/ocr/invoice_splitter_async/invoice_splitter_async_args.py (0 hunks)
  • edenai_apis/features/ocr/ocr/ocr_args.py (0 hunks)
  • edenai_apis/features/ocr/ocr_async/ocr_async_args.py (0 hunks)
  • edenai_apis/features/ocr/ocr_tables_async/ocr_tables_async_args.py (0 hunks)
  • edenai_apis/features/ocr/receipt_parser/receipt_parser_args.py (0 hunks)
  • edenai_apis/features/ocr/receipt_parser/receipt_parser_dataclass.py (1 hunks)
  • edenai_apis/features/text/chat/__init__.py (1 hunks)
  • edenai_apis/features/text/emotion_detection/__init__.py (1 hunks)
  • edenai_apis/features/text/emotion_detection/emotion_detection_args.py (1 hunks)
  • edenai_apis/features/text/entity_sentiment/entities.py (1 hunks)
  • edenai_apis/features/text/moderation/moderation_dataclass.py (1 hunks)
  • edenai_apis/features/text/moderation/pattern.py (10 hunks)
  • edenai_apis/features/text/plagia_detection/__init__.py (1 hunks)
  • edenai_apis/features/text/plagia_detection/plagia_detection_args.py (1 hunks)
  • edenai_apis/features/text/plagia_detection/plagia_detection_dataclass.py (1 hunks)
  • edenai_apis/features/text/prompt_optimization/prompt_optimization_args.py (1 hunks)
  • edenai_apis/features/text/search/search_args.py (1 hunks)
  • edenai_apis/features/translation/document_translation/document_translation_args.py (0 hunks)
  • edenai_apis/features/video/explicit_content_detection_async/explicit_content_detection_async_args.py (0 hunks)
  • edenai_apis/features/video/face_detection_async/face_detection_async_args.py (0 hunks)
  • edenai_apis/features/video/label_detection_async/label_detection_async_args.py (0 hunks)
  • edenai_apis/features/video/object_tracking_async/object_tracking_async_args.py (0 hunks)
  • edenai_apis/features/video/person_tracking_async/person_tracking_async_args.py (0 hunks)
  • edenai_apis/features/video/shot_change_detection_async/shot_change_detection_async_args.py (0 hunks)
  • edenai_apis/features/video/shot_change_detection_async/shot_change_detection_async_dataclass.py (1 hunks)
  • edenai_apis/interface.py (1 hunks)
  • edenai_apis/llmengine/clients/__init__.py (4 hunks)
  • edenai_apis/llmengine/clients/litellm_client/__init__.py (2 hunks)
  • edenai_apis/llmengine/providers/__init__.py (2 hunks)
  • edenai_apis/llmengine/providers/utils.py (1 hunks)
  • edenai_apis/llmengine/tests/test_llm_engine.py (1 hunks)
  • edenai_apis/llmengine/tests/test_model_management_interface.py (1 hunks)
  • edenai_apis/llmengine/tests/test_tools.py (2 hunks)
  • edenai_apis/llmengine/types/litellm_model.py (2 hunks)
  • edenai_apis/llmengine/types/response_types.py (3 hunks)
  • edenai_apis/llmengine/types/tools_types.py (2 hunks)
  • edenai_apis/loaders/loaders.py (2 hunks)
  • edenai_apis/scripts/check_not_working_providers.py (1 hunks)
  • edenai_apis/tests/features/test_async_features.py (1 hunks)
  • edenai_apis/tests/features/test_sync_features.py (1 hunks)
  • edenai_apis/tests/test_classes.py (1 hunks)
  • edenai_apis/tests/test_interface.py (1 hunks)
  • edenai_apis/tests/utils/test_compare.py (1 hunks)
  • edenai_apis/tests/utils/test_languages.py (1 hunks)
  • edenai_apis/utils/bounding_box.py (2 hunks)
  • edenai_apis/utils/combine_enums.py (1 hunks)
  • edenai_apis/utils/exception.py (1 hunks)
  • edenai_apis/utils/files.py (1 hunks)
  • edenai_apis/utils/metrics.py (3 hunks)
  • edenai_apis/utils/monitoring.py (0 hunks)
  • edenai_apis/utils/ssml.py (1 hunks)
💤 Files with no reviewable changes (27)
  • edenai_apis/features/image/landmark_detection/landmark_detection_args.py
  • edenai_apis/features/image/embeddings/embeddings_args.py
  • edenai_apis/features/ocr/invoice_splitter_async/invoice_splitter_async_args.py
  • edenai_apis/apis/twelvelabs/init.py
  • edenai_apis/features/ocr/receipt_parser/receipt_parser_args.py
  • edenai_apis/features/video/face_detection_async/face_detection_async_args.py
  • edenai_apis/features/image/background_removal/background_removal_args.py
  • edenai_apis/features/video/explicit_content_detection_async/explicit_content_detection_async_args.py
  • edenai_apis/features/ocr/ocr_async/ocr_async_args.py
  • edenai_apis/features/translation/document_translation/document_translation_args.py
  • edenai_apis/features/image/generation_fine_tuning/create_project_async/generation_fine_tuning_create_project_async_args.py
  • edenai_apis/features/video/person_tracking_async/person_tracking_async_args.py
  • edenai_apis/features/ocr/ocr_tables_async/ocr_tables_async_args.py
  • edenai_apis/features/image/face_recognition/add_face/face_recognition_add_face_args.py
  • edenai_apis/features/image/search/upload_image/search_upload_image_args.py
  • edenai_apis/features/image/face_compare/face_compare_args.py
  • edenai_apis/features/ocr/custom_document_parsing_async/custom_document_parsing_async_args.py
  • edenai_apis/features/image/automl_classification/upload_data_async/automl_classification_upload_data_async_args.py
  • edenai_apis/features/image/face_recognition/recognize/face_recognition_recognize_args.py
  • edenai_apis/features/video/label_detection_async/label_detection_async_args.py
  • edenai_apis/features/video/shot_change_detection_async/shot_change_detection_async_args.py
  • edenai_apis/features/image/face_detection/face_detection_args.py
  • edenai_apis/features/ocr/ocr/ocr_args.py
  • edenai_apis/utils/monitoring.py
  • edenai_apis/features/video/object_tracking_async/object_tracking_async_args.py
  • edenai_apis/features/ocr/invoice_parser/invoice_parser_args.py
  • edenai_apis/features/image/search/launch_similarity/search_launch_similarity_args.py
✅ Files skipped from review due to trivial changes (71)
  • edenai_apis/apis/affinda/models.py
  • edenai_apis/features/ocr/anonymization_async/anonymization_async_args.py
  • edenai_apis/features/text/emotion_detection/emotion_detection_args.py
  • edenai_apis/features/ocr/receipt_parser/receipt_parser_dataclass.py
  • edenai_apis/apis/senseloaf/models.py
  • edenai_apis/features/image/automl_classification/predict_async/automl_classification_predict_async_args.py
  • edenai_apis/features/text/prompt_optimization/prompt_optimization_args.py
  • edenai_apis/utils/combine_enums.py
  • edenai_apis/features/video/shot_change_detection_async/shot_change_detection_async_dataclass.py
  • edenai_apis/features/image/variation/variation_dataclass.py
  • edenai_apis/features/image/anonymization/anonymization_args.py
  • edenai_apis/apis/replicate/config.py
  • edenai_apis/llmengine/types/response_types.py
  • edenai_apis/scripts/check_not_working_providers.py
  • edenai_apis/tests/features/test_sync_features.py
  • edenai_apis/apis/amazon/config.py
  • edenai_apis/features/text/search/search_args.py
  • edenai_apis/tests/utils/test_compare.py
  • edenai_apis/features/image/explicit_content/category.py
  • edenai_apis/utils/files.py
  • edenai_apis/llmengine/providers/init.py
  • edenai_apis/apis/privateai/errors.py
  • edenai_apis/apis/senseloaf/client.py
  • edenai_apis/features/text/entity_sentiment/entities.py
  • edenai_apis/apis/elevenlabs/errors.py
  • edenai_apis/apis/corticalio/client.py
  • edenai_apis/features/image/search/get_image/search_get_image_args.py
  • edenai_apis/llmengine/providers/utils.py
  • edenai_apis/apis/anthropic/errors.py
  • edenai_apis/interface.py
  • edenai_apis/apis/gladia/errors.py
  • edenai_apis/apis/leonardo/config.py
  • edenai_apis/features/text/plagia_detection/plagia_detection_args.py
  • edenai_apis/tests/utils/test_languages.py
  • edenai_apis/apis/faker/faker_api.py
  • edenai_apis/apis/google/errors.py
  • edenai_apis/apis/meta/errors.py
  • edenai_apis/apis/corticalio/helpers.py
  • edenai_apis/features/ocr/anonymization_async/anonymization_async_dataclass.py
  • edenai_apis/apis/senseloaf/errors.py
  • edenai_apis/llmengine/tests/test_llm_engine.py
  • edenai_apis/features/ocr/invoice_parser/invoice_parser_dataclass.py
  • edenai_apis/llmengine/types/litellm_model.py
  • edenai_apis/apis/mindee/mindee_ocr_normalizer.py
  • edenai_apis/features/image/search/delete_image/search_delete_image_args.py
  • edenai_apis/utils/metrics.py
  • edenai_apis/apis/senseloaf/remapping.py
  • edenai_apis/apis/ai21labs/errors.py
  • edenai_apis/features/ocr/bank_check_parsing/bank_check_parsing_args.py
  • edenai_apis/features/ocr/data_extraction/data_extraction_args.py
  • edenai_apis/utils/exception.py
  • edenai_apis/tests/test_interface.py
  • edenai_apis/llmengine/clients/litellm_client/init.py
  • edenai_apis/features/ocr/identity_parser/identity_parser_dataclass.py
  • edenai_apis/apis/together_ai/errors.py
  • edenai_apis/features/image/ai_detection/ai_detection_args.py
  • edenai_apis/tests/test_classes.py
  • edenai_apis/apis/affinda/document.py
  • edenai_apis/features/image/search/get_images/search_get_images_args.py
  • edenai_apis/apis/mistral/errors.py
  • edenai_apis/apis/klippa/klippa_ocr_normalizer.py
  • edenai_apis/features/ocr/financial_parser/financial_parser_dataclass.py
  • edenai_apis/llmengine/types/tools_types.py
  • edenai_apis/loaders/loaders.py
  • edenai_apis/apis/writesonic/writesonic_api.py
  • edenai_apis/utils/ssml.py
  • edenai_apis/utils/bounding_box.py
  • edenai_apis/llmengine/tests/test_model_management_interface.py
  • edenai_apis/llmengine/clients/init.py
  • edenai_apis/apis/dataleon/dataleon_ocr_normalizer.py
  • edenai_apis/tests/features/test_async_features.py
🚧 Files skipped from review as they are similar to previous changes (2)
  • edenai_apis/apis/amazon/amazon_api.py
  • edenai_apis/apis/google/google_api.py
🧰 Additional context used
🪛 Ruff (0.8.2)
edenai_apis/apis/meta/meta_api.py

136-136: Do not use mutable data structures for argument defaults

Replace with None; initialize within function

(B006)

edenai_apis/apis/mistral/mistral_api.py

157-157: Do not use mutable data structures for argument defaults

Replace with None; initialize within function

(B006)

edenai_apis/apis/together_ai/together_ai_api.py

69-69: Do not use mutable data structures for argument defaults

Replace with None; initialize within function

(B006)

edenai_apis/apis/openai/openai_llm_api.py

1-1: typing.Dict imported but unused

Remove unused import: typing.Dict

(F401)


3-3: openai.OpenAI imported but unused

Remove unused import: openai.OpenAI

(F401)


4-4: openai.NOT_GIVEN imported but unused

Remove unused import: openai.NOT_GIVEN

(F401)


13-13: Do not use mutable data structures for argument defaults

Replace with None; initialize within function

(B006)

edenai_apis/apis/affinda/tests/test_client.py

45-45: Local variable organization is assigned to but never used

Remove assignment to unused variable organization

(F841)


125-125: Local variable workspace is assigned to but never used

Remove assignment to unused variable workspace

(F841)

edenai_apis/apis/anthropic/anthropic_api.py

142-142: Do not use mutable data structures for argument defaults

Replace with None; initialize within function

(B006)

edenai_apis/apis/replicate/replicate_api.py

247-247: Do not use mutable data structures for argument defaults

Replace with None; initialize within function

(B006)

edenai_apis/__init__.py

21-21: .apis imported but unused; consider removing, adding to __all__, or using a redundant alias

(F401)


22-22: .features imported but unused; consider removing, adding to __all__, or using a redundant alias

(F401)


23-23: .interface imported but unused; consider removing, adding to __all__, or using a redundant alias

(F401)


24-24: .loaders imported but unused; consider removing, adding to __all__, or using a redundant alias

(F401)


25-25: .settings imported but unused; consider removing, adding to __all__, or using a redundant alias

(F401)


26-26: .utils imported but unused; consider removing, adding to __all__, or using a redundant alias

(F401)


27-27: .interface_v2.Text imported but unused; consider removing, adding to __all__, or using a redundant alias

(F401)


27-27: .interface_v2.Ocr imported but unused; consider removing, adding to __all__, or using a redundant alias

(F401)


27-27: .interface_v2.Video imported but unused; consider removing, adding to __all__, or using a redundant alias

(F401)


27-27: .interface_v2.Audio imported but unused; consider removing, adding to __all__, or using a redundant alias

(F401)


27-27: .interface_v2.Image imported but unused; consider removing, adding to __all__, or using a redundant alias

(F401)


27-27: .interface_v2.Translation imported but unused; consider removing, adding to __all__, or using a redundant alias

(F401)


27-27: .interface_v2.Multimodal imported but unused; consider removing, adding to __all__, or using a redundant alias

(F401)


27-27: .interface_v2.LLM imported but unused; consider removing, adding to __all__, or using a redundant alias

(F401)

edenai_apis/apis/affinda/standardization.py

5-5: edenai_apis.features.ocr.financial_parser.FinancialBarcode imported but unused

Remove unused import: edenai_apis.features.ocr.financial_parser.FinancialBarcode

(F401)

edenai_apis/apis/alephalpha/__init__.py

1-1: .alephalpha_api.AlephAlphaApi imported but unused; consider removing, adding to __all__, or using a redundant alias

(F401)

edenai_apis/apis/amazon/amazon_llm_api.py

15-15: Do not use mutable data structures for argument defaults

Replace with None; initialize within function

(B006)


31-31: Do not use mutable data structures for argument defaults

Replace with None; initialize within function

(B006)

edenai_apis/apis/astria/__init__.py

1-1: .astria_api.AstriaApi imported but unused; consider removing, adding to __all__, or using a redundant alias

(F401)

edenai_apis/apis/base64/base64_helpers.py

126-126: Loop control variable page_index not used within loop body

(B007)

edenai_apis/apis/corticalio/__init__.py

1-1: .corticalio_api.CorticalioApi imported but unused; consider removing, adding to __all__, or using a redundant alias

(F401)

edenai_apis/apis/corticalio/tests/test_cortical_client.py

51-51: Local variable e is assigned to but never used

Remove assignment to unused variable e

(F841)

edenai_apis/apis/gladia/__init__.py

1-1: .gladia_api.GladiaApi imported but unused; consider removing, adding to __all__, or using a redundant alias

(F401)

edenai_apis/apis/jina/__init__.py

1-1: .jina_api.JinaApi imported but unused; consider removing, adding to __all__, or using a redundant alias

(F401)

edenai_apis/apis/leonardo/__init__.py

1-1: .leonardo_api.LeonardoApi imported but unused; consider removing, adding to __all__, or using a redundant alias

(F401)

edenai_apis/apis/lovoai/config.py

242-242: Dictionary key literal "kn-IN_Aadesh Madar" repeated

Remove repeated key literal "kn-IN_Aadesh Madar"

(F601)

edenai_apis/apis/perplexityai/__init__.py

1-1: .perplexityai_api.PerplexityApi imported but unused; consider removing, adding to __all__, or using a redundant alias

(F401)

edenai_apis/apis/readyredact/__init__.py

1-1: .readyredact_api.ReadyRedactApi imported but unused; consider removing, adding to __all__, or using a redundant alias

(F401)

edenai_apis/apis/sapling/__init__.py

1-1: .sapling_api.SaplingApi imported but unused; consider removing, adding to __all__, or using a redundant alias

(F401)

edenai_apis/apis/senseloaf/__init__.py

1-1: .senseloaf_api.SenseloafApi imported but unused; consider removing, adding to __all__, or using a redundant alias

(F401)

edenai_apis/apis/sightengine/__init__.py

1-1: .sightengine_api.SightEngineApi imported but unused; consider removing, adding to __all__, or using a redundant alias

(F401)

edenai_apis/apis/together_ai/__init__.py

1-1: .together_ai_api.TogetheraiApi imported but unused; consider removing, adding to __all__, or using a redundant alias

(F401)

edenai_apis/features/image/embeddings/__init__.py

2-2: .embeddings_dataclass.EmbeddingDataClass imported but unused; consider removing, adding to __all__, or using a redundant alias

(F401)


2-2: .embeddings_dataclass.EmbeddingsDataClass imported but unused; consider removing, adding to __all__, or using a redundant alias

(F401)

edenai_apis/features/ocr/anonymization_async/__init__.py

2-2: .anonymization_async_dataclass.AnonymizationAsyncDataClass imported but unused; consider removing, adding to __all__, or using a redundant alias

(F401)

edenai_apis/features/ocr/financial_parser/__init__.py

13-13: .financial_parser_dataclass.FinancialParserDataClass imported but unused; consider removing, adding to __all__, or using a redundant alias

(F401)

edenai_apis/features/text/chat/__init__.py

3-3: .chat_dataclass.ChatDataClass imported but unused; consider removing, adding to __all__, or using a redundant alias

(F401)


4-4: .chat_dataclass.ChatMessageDataClass imported but unused; consider removing, adding to __all__, or using a redundant alias

(F401)


5-5: .chat_dataclass.StreamChat imported but unused; consider removing, adding to __all__, or using a redundant alias

(F401)


6-6: .chat_dataclass.ChatStreamResponse imported but unused; consider removing, adding to __all__, or using a redundant alias

(F401)

edenai_apis/features/text/emotion_detection/__init__.py

3-3: .emotion_detection_dataclass.EmotionDetectionDataClass imported but unused; consider removing, adding to __all__, or using a redundant alias

(F401)


4-4: .emotion_detection_dataclass.EmotionItem imported but unused; consider removing, adding to __all__, or using a redundant alias

(F401)


5-5: .emotion_detection_dataclass.EmotionEnum imported but unused; consider removing, adding to __all__, or using a redundant alias

(F401)

edenai_apis/features/text/plagia_detection/__init__.py

5-5: .plagia_detection_dataclass.PlagiaDetectionDataClass imported but unused; consider removing, adding to __all__, or using a redundant alias

(F401)

edenai_apis/features/text/plagia_detection/plagia_detection_dataclass.py

14-14: Use values.get("plagia_score") instead of values.get("plagia_score", None)

Replace values.get("plagia_score", None) with values.get("plagia_score")

(SIM910)

🪛 GitHub Actions: CICD
edenai_apis/apis/amazon/amazon_llm_api.py

[error] 5-5: ImportError: cannot import name 'AmazonLLMApi' from partially initialized module 'edenai_apis.apis.amazon.amazon_llm_api' (most likely due to a circular import)


[error] 5-5: ImportError: cannot import name 'AmazonLLMApi' from partially initialized module 'edenai_apis.apis.amazon.amazon_llm_api' (most likely due to a circular import)

edenai_apis/features/text/plagia_detection/plagia_detection_dataclass.py

[warning] 12-12: Pydantic V1 style @root_validator validators are deprecated. You should migrate to Pydantic V2 style @model_validator validators.

🔇 Additional comments (87)
edenai_apis/llmengine/tests/test_tools.py (3)

165-171: The tool_calls structure looks clean and easier to read.

The updated JSON representation with single quotes for the inner JSON string ('{"n":"5"}') is more readable than using escaped double quotes. This is a good improvement to the code readability.


186-191: Improved readability with multi-line assertion.

Breaking the complex assertion into multiple lines improves readability while maintaining the same logical check.


144-191: Consider making mock tool function behavior more realistic.

The test mocks the tool calls but doesn't test the actual execution of the factorial function. It would be more robust to verify that the function produces the expected results when called with the provided arguments.

You might want to extend this test to verify that the tool execution works correctly by checking the results returned after processing the tool call, not just verifying that the correct function was called.

edenai_apis/features/text/plagia_detection/plagia_detection_dataclass.py (1)

34-37: Cosmetic Formatting Enhancements Approved.
The spacing adjustments in the PlagiaDetectionDataClass (lines 35–36) improve code readability and align with standard formatting conventions.

edenai_apis/features/image/explicit_content/pattern.py (8)

15-15: Formatting improvements enhance code readability.

The addition of empty lines between class declarations and their contents creates better visual separation, making the code structure clearer and easier to navigate.

Also applies to: 27-27, 48-48, 72-72, 103-103, 143-143, 166-166, 181-181, 195-195, 208-208


77-82: Well-structured categorization for NUDITY content.

The restructuring of the NUDITY constant as a multi-line list improves readability and maintainability. The comprehensive categorization with specific types (graphic male nudity, graphic female nudity, etc.) provides more granular content detection capabilities.


84-90: Comprehensive categorization for SUGGESTIVE content.

The restructuring of the SUGGESTIVE constant as a multi-line list improves readability. The expanded list with gender-specific categories (female/male swimwear) and additional types of suggestive content enhances the content detection system's precision.


104-115: Expanded violence detection with detailed categories.

The GRAPHIC_VIOLENCE_OR_GORE constant now encompasses a wider range of violent content types, including specific scenarios like "emaciated bodies", "air crash", and "explosions and blasts". This enhancement will improve the system's ability to identify and categorize various forms of graphic content.


116-122: Comprehensive self-harm and physical violence categorization.

The PHYSICAL_VIOLENCE constant now includes detailed patterns for self-harm detection, with subcategories for intent and instructions. This improvement allows for more nuanced detection of content related to physical harm.


123-129: Enhanced weapons-related content detection.

The WEAPON_VIOLENCE constant has been expanded to include broader categories like "war & conflict" alongside specific weapon-related patterns. This provides more comprehensive coverage for detecting violent content involving weapons.


144-151: Expanded drug-related content detection capabilities.

The DRUG_PRODUCTS constant now includes a more comprehensive list of drug-related patterns, enhancing the system's ability to detect various forms of drug content in images.


31-32:

✅ Verification successful

Verify consistency between class documentation and implementations.

The code adds several new constants that align with the class documentation. Ensure that all new constants (PROFANITY, THREAT, EXPLICIT, QRCODE, MEDICAL, POLITICS, LEGAL, ALCOHOL, GAMBLING, EXTREMIST, RACY, NOT_SAFE, OTHER) are properly included in any mapping or processing logic that consumes these patterns.

Also applies to: 52-56, 155-155, 167-167, 185-186, 196-196, 212-212


🏁 Script executed:

#!/bin/bash
# Check if these new constants are referenced elsewhere in the codebase

echo "Searching for references to new pattern constants in the codebase..."

# Check for explicit references to these constants
echo "=== References to new constants ==="
rg -A 3 "SubCategoryPattern\.(Toxic|Content|DrugAndAlcohol|Finance|HateAndExtremism|Safe|Other)\.(PROFANITY|THREAT|EXPLICIT|QRCODE|MEDICAL|POLITICS|LEGAL|ALCOHOL|GAMBLING|EXTREMIST|RACY|NOT_SAFE|OTHER)"

# Check for pattern mapping files that might need updates
echo "=== Pattern mapping files ==="
fd "pattern.*\.py" --exclude="pattern.py"

# Check for parsers or integrations that might use these patterns
echo "=== Possible integration points ==="
rg -l "explicit_content.*pattern" --type py

Length of output: 7318


Mapping Consistency Validated

The new constants defined in edenai_apis/features/image/explicit_content/pattern.py (i.e., PROFANITY, THREAT, EXPLICIT, QRCODE, MEDICAL, POLITICS, LEGAL, ALCOHOL, GAMBLING, EXTREMIST, RACY, NOT_SAFE, and OTHER) are properly integrated into the mapping logic. The recent searches confirm that these constants are referenced consistently within the subcategory mapping files (notably in edenai_apis/features/image/explicit_content/subcategory.py as well as in the corresponding text module mappings). The implementation is aligned with the class documentation.

  • Ensure that any future integrations or processing logic continue to reference these constants accordingly.
edenai_apis/apis/affinda/standardization.py (2)

3-15: Improved Import Formatting

The grouping and vertical alignment of the import statements (e.g., from financial_parser, identity_parser, etc.) enhance their readability and maintainability. This cosmetic refactoring is well‑structured. Please ensure that any code relying on these imported entities continues to work as expected after the reformat.

🧰 Tools
🪛 Ruff (0.8.2)

5-5: edenai_apis.features.ocr.financial_parser.FinancialBarcode imported but unused

Remove unused import: edenai_apis.features.ocr.financial_parser.FinancialBarcode

(F401)


16-23: Consistent Import Structure

The revised import block from identity_parser (and subsequent grouped imports) contributes to a more consistent code style across modules. There are no functional changes here, so the improved formatting is approved.

edenai_apis/apis/lovoai/config.py (1)

1-9: Updated voice_ids Dictionary

The replacement of the entire voice_ids dictionary with new key-value pairs correctly aligns with the update objectives. Please verify that the new unique identifiers are accurate and that any dependent functionality (e.g., voice selection logic) is updated accordingly.

edenai_apis/apis/openai/openai_llm_api.py (1)

52-86: The method implementation looks good.

The implementation passes all received parameters to self.std_llm_client.completion as expected, following the OpenAI compatibility approach mentioned in the PR objectives.

edenai_apis/apis/corticalio/tests/test_cortical_client.py (5)

17-17: Formatting improvement looks good.

The return statement is now more concise and readable.


22-24: Formatting improvement looks good.

The multiline formatting for outputs_path improves readability.


40-42: List comprehension formatting improvement looks good.

Breaking the list comprehension into multiple lines enhances readability.


49-49: responses.add formatting improvement looks good.

Breaking the responses.add methods into multiple lines makes the parameters more readable.

Also applies to: 57-62


65-65: String formatting consistency improvement looks good.

Changing to double quotes for string literals improves consistency with the rest of the file.

edenai_apis/apis/base64/base64_helpers.py (5)

15-16: Adding trailing commas in import statements is a good practice.

Adding trailing commas after the last item in import statements makes future modifications easier and prevents potential syntax errors when adding new imports.

Also applies to: 25-26, 35-36


112-113: String formatting consistency improvement.

Changing from single quotes to double quotes for the regex pattern improves consistency with other string literals in the codebase.


118-118: Simplified dictionary update formatting looks good.

The single-line format for the dictionary update is more concise.


136-136: Simplified function call and variable assignment formatting looks good.

The single-line format for these assignments improves readability.

Also applies to: 162-162, 264-264


371-407: Improved vertical alignment of parameters.

The reorganization of method parameters with consistent vertical alignment improves readability significantly.

edenai_apis/apis/affinda/tests/test_client.py (2)

18-19: String formatting consistency improvement looks good.

Using double quotes instead of single quotes for string literals improves consistency.


25-27: Formatting improvements for better readability.

The multiline formatting of assertions, context managers, and list comprehensions significantly improves code readability while maintaining the same functionality.

Also applies to: 31-33, 53-55, 59-61, 67-69, 72-75, 77-79, 83-85, 101-103, 116-118, 121-124, 130-132, 135-137, 149-151, 156-160, 164-166, 169-171, 176-178, 181-185, 190-192, 196-199, 201-203, 207-211, 222-224, 229-233, 238-240, 247-249, 254-258, 261-265, 270-272, 277-281, 286-288, 292-295, 299-301, 306-308, 313-319, 323-327, 331-333, 338-339, 342-346, 351-353, 358-362, 382-384, 389-393, 407-409, 415-418

edenai_apis/features/text/moderation/pattern.py (23)

15-15: LGTM: Code formatting improves readability.

Adding a blank line after the class docstring and before the first class improves readability and follows PEP 8 guidelines.


27-27: LGTM: Proper separation between class attributes.

Adding a blank line between the docstring and the class constants follows good coding practices.


31-32: LGTM: Added important moderation patterns.

The addition of PROFANITY and THREAT constants enhances the moderation capabilities of the system.


48-48: LGTM: Proper spacing between docstring and class attributes.

Adding a blank line after the class docstring improves readability and follows style guidelines.


52-56: LGTM: Expanded content moderation patterns.

The addition of new content moderation constants (EXPLICIT, QRCODE, MEDICAL, POLITICS, LEGAL) increases the system's capability to identify and categorize different types of content.


72-72: LGTM: Proper docstring spacing.

Consistent spacing after docstrings improves code readability.


77-82: LGTM: Improved format for multi-value constants.

Reformatting the NUDITY constant as a multi-line list improves readability and maintainability, especially as it now contains multiple related patterns.


84-90: LGTM: Consistent multi-line formatting.

Applying the same multi-line formatting to the SUGGESTIVE constant maintains consistency in the codebase.


103-103: LGTM: Consistent spacing.

Consistent spacing after docstrings throughout the file.


104-115: LGTM: Comprehensive violence detection patterns.

The expanded GRAPHIC_VIOLENCE_OR_GORE constant with multiple specific patterns enables more granular violence content detection.


116-122: LGTM: Added self-harm pattern detection.

The PHYSICAL_VIOLENCE category now includes important self-harm detection patterns, enhancing safety capabilities.


123-129: LGTM: Enhanced weapon violence detection.

Expanding the WEAPON_VIOLENCE constant with additional patterns improves the system's ability to detect various weapon-related content.


143-143: LGTM: Consistent docstring spacing.

Maintaining consistent spacing after docstrings throughout the file.


144-151: LGTM: Expanded drug detection patterns.

Reformatted DRUG_PRODUCTS with comprehensive patterns enhances the system's ability to identify drug-related content.


155-155: LGTM: Added alcohol detection.

The addition of the ALCOHOL constant improves categorization capabilities for substance-related content.


166-166: LGTM: Consistent spacing.

Maintaining consistent spacing after docstrings throughout the file.


167-167: LGTM: Added gambling detection.

The addition of the GAMBLING constant enhances the finance-related content moderation capabilities.


181-181: LGTM: Consistent spacing.

Maintaining consistent spacing after docstrings throughout the file.


185-186: LGTM: Enhanced extremism detection.

The addition of EXTREMIST and RACY constants provides more specific categorization for potentially problematic content.


195-195: LGTM: Consistent spacing.

Maintaining consistent spacing after docstrings throughout the file.


196-196: LGTM: Added safety classification.

The addition of the NOT_SAFE constant provides a clearer binary classification for content safety.


208-208: LGTM: Consistent spacing.

Maintaining consistent spacing after docstrings throughout the file.


212-212: LGTM: Added general categorization.

The addition of the OTHER constant provides a fallback category for content that doesn't fit into specific classifications.

edenai_apis/__init__.py (1)

27-27: LGTM: Important addition of LLM to the interface exports.

Adding the LLM class to the imports makes it accessible at the package level, which aligns with the PR objective of integrating OpenAI-compatible chat API functionality.

The static analysis shows these imports as unused, but this is expected in __init__.py files where imports make entities available at the package level.

🧰 Tools
🪛 Ruff (0.8.2)

27-27: .interface_v2.Text imported but unused; consider removing, adding to __all__, or using a redundant alias

(F401)


27-27: .interface_v2.Ocr imported but unused; consider removing, adding to __all__, or using a redundant alias

(F401)


27-27: .interface_v2.Video imported but unused; consider removing, adding to __all__, or using a redundant alias

(F401)


27-27: .interface_v2.Audio imported but unused; consider removing, adding to __all__, or using a redundant alias

(F401)


27-27: .interface_v2.Image imported but unused; consider removing, adding to __all__, or using a redundant alias

(F401)


27-27: .interface_v2.Translation imported but unused; consider removing, adding to __all__, or using a redundant alias

(F401)


27-27: .interface_v2.Multimodal imported but unused; consider removing, adding to __all__, or using a redundant alias

(F401)


27-27: .interface_v2.LLM imported but unused; consider removing, adding to __all__, or using a redundant alias

(F401)

edenai_apis/features/text/emotion_detection/__init__.py (1)

2-6: LGTM: Improved import formatting.

Changing the single-line import to a multi-line format improves readability and follows best practices for imports with multiple classes.

The static analysis flags these imports as unused, but this is normal for __init__.py files that expose these entities to package users.

🧰 Tools
🪛 Ruff (0.8.2)

3-3: .emotion_detection_dataclass.EmotionDetectionDataClass imported but unused; consider removing, adding to __all__, or using a redundant alias

(F401)


4-4: .emotion_detection_dataclass.EmotionItem imported but unused; consider removing, adding to __all__, or using a redundant alias

(F401)


5-5: .emotion_detection_dataclass.EmotionEnum imported but unused; consider removing, adding to __all__, or using a redundant alias

(F401)

edenai_apis/features/text/chat/__init__.py (1)

2-7: LGTM: Improved import formatting.

Converting the single-line import to a multi-line format enhances readability and consistency, especially important for chat functionality that's being enhanced in this PR.

The static analysis flags these imports as unused, but this is standard for __init__.py files that expose these entities to package users.

🧰 Tools
🪛 Ruff (0.8.2)

3-3: .chat_dataclass.ChatDataClass imported but unused; consider removing, adding to __all__, or using a redundant alias

(F401)


4-4: .chat_dataclass.ChatMessageDataClass imported but unused; consider removing, adding to __all__, or using a redundant alias

(F401)


5-5: .chat_dataclass.StreamChat imported but unused; consider removing, adding to __all__, or using a redundant alias

(F401)


6-6: .chat_dataclass.ChatStreamResponse imported but unused; consider removing, adding to __all__, or using a redundant alias

(F401)

edenai_apis/features/text/moderation/moderation_dataclass.py (1)

44-47: LGTM! Clear addition of a new offensive content category.

The added "offensive" category enriches the moderation capabilities of the Microsoft enumeration, enabling more granular content categorization.

edenai_apis/apis/together_ai/together_ai_api.py (5)

14-15: LGTM! Appropriate imports for LLM interface implementation.

The new imports properly set up the required dependencies for adding OpenAI-compatible chat capabilities.


18-18: LGTM! Interface implementation aligns with PR objectives.

Adding LlmInterface to the class signature appropriately implements the OpenAI compatibility requirement mentioned in the PR objectives.


32-34: LGTM! Proper StdLLMEngine initialization.

Initializing the standard LLM client with the API key enables the OpenAI-compatible interface implementation.


69-69: Use a non-mutable default for messages.

Initializing messages as an empty list by default can cause shared-state issues. Use None instead and set it inside the function.

-def llm__chat(
-    self,
-    messages: List = [],
+def llm__chat(
+    self,
+    messages: Optional[List] = None,

Then add initialization inside the function:

     def llm__chat(
         self,
-        messages: List = [],
+        messages: Optional[List] = None,
         model: Optional[str] = None,
         # Optional OpenAI params: see https://platform.openai.com/docs/api-reference/chat/create
         timeout: Optional[Union[float, str, httpx.Timeout]] = None,
         ...
     ) -> ChatCompletionResponse:
+        if messages is None:
+            messages = []
         response = self.std_llm_client.completion(
🧰 Tools
🪛 Ruff (0.8.2)

69-69: Do not use mutable data structures for argument defaults

Replace with None; initialize within function

(B006)


67-107: LGTM! Comprehensive implementation of OpenAI-compatible chat interface.

The method signature and implementation align well with the PR objective of making Eden AI chat API OpenAI compatible. All standard parameters are properly included and passed through to the StdLLMEngine.

🧰 Tools
🪛 Ruff (0.8.2)

69-69: Do not use mutable data structures for argument defaults

Replace with None; initialize within function

(B006)

edenai_apis/apis/anthropic/anthropic_api.py (4)

25-26: LGTM! Appropriate imports for LLM interface.

The imports correctly set up the necessary dependencies for implementing the OpenAI-compatible chat functionality.


29-29: LGTM! Interface implementation matches PR objectives.

Adding LlmInterface to AnthropicApi class signature properly implements the OpenAI compatibility requirement.


44-49: LGTM! Proper StdLLMEngine initialization with caching config.

The standard LLM client is correctly initialized with the API key and ephemeral cache control settings.


140-215: LGTM! Comprehensive implementation of OpenAI-compatible chat endpoint.

The method properly implements all the OpenAI API parameters and passes them through to the StdLLMEngine, supporting the PR objective of OpenAI compatibility.

🧰 Tools
🪛 Ruff (0.8.2)

142-142: Do not use mutable data structures for argument defaults

Replace with None; initialize within function

(B006)

edenai_apis/apis/amazon/amazon_llm_api.py (4)

21-27: LGTM! Proper StdLLMEngine initialization with AWS credentials.

The LLM client is correctly initialized with AWS credentials and region configuration.


31-31: Fix mutable default argument for messages.

Using a mutable default value (empty list) can cause unexpected behavior when the function is called multiple times.

-    def llm__chat(
-        self,
-        messages: List = [],
+    def llm__chat(
+        self,
+        messages: Optional[List] = None,

Add initialization inside the function:

     def llm__chat(
         self,
-        messages: List = [],
+        messages: Optional[List] = None,
         model: Optional[str] = None,
         ...
     ) -> ChatCompletionResponse:
+        if messages is None:
+            messages = []
         response = self.llm_client.completion(
🧰 Tools
🪛 Ruff (0.8.2)

31-31: Do not use mutable data structures for argument defaults

Replace with None; initialize within function

(B006)


29-104: LGTM! Comprehensive implementation of OpenAI-compatible chat interface.

The method signature and implementation are well-aligned with the PR objective of making Eden AI chat API OpenAI compatible. All standard parameters are properly included and passed through to the LLM engine.

🧰 Tools
🪛 Ruff (0.8.2)

31-31: Do not use mutable data structures for argument defaults

Replace with None; initialize within function

(B006)


13-13: LGTM! Well-defined interface implementation.

The AmazonLLMApi class correctly implements the LlmInterface to provide OpenAI-compatible chat functionality.

edenai_apis/apis/mistral/mistral_api.py (5)

1-2: Imports look fine
No issues noted.


21-23: Additional imports for LLM functionality
These are necessary for the new feature and look good.


26-26: Added LlmInterface Inheritance
Aligns with the broader changes for LLM support.


40-40: Instantiating StdLLMEngine
Implementation matches the standard approach in this PR.


154-229: Avoid using mutable default arguments
Using messages: List = [] can cause unexpected side effects.

-    def llm__chat(
-        self,
-        messages: List = [],
+    def llm__chat(
+        self,
+        messages: Optional[List] = None,
         ...
     ):
+        if messages is None:
+            messages = []
🧰 Tools
🪛 Ruff (0.8.2)

157-157: Do not use mutable data structures for argument defaults

Replace with None; initialize within function

(B006)

edenai_apis/apis/meta/meta_api.py (2)

1-4: Expanded imports and LlmInterface integration
These changes consistently introduce LLM functionality.

Also applies to: 20-20, 24-25, 28-28, 50-50


132-210: Avoid using mutable default arguments
Same concern about messages: List = [].

-    def llm__chat(
-        self,
-        messages: List = [],
+    def llm__chat(
+        self,
+        messages: Optional[List] = None,
         ...
     ):
+        if messages is None:
+            messages = []
🧰 Tools
🪛 Ruff (0.8.2)

136-136: Do not use mutable data structures for argument defaults

Replace with None; initialize within function

(B006)

edenai_apis/apis/veryfi/veryfi_ocr_normalizer.py (9)

40-40: Trivial formatting update
No functional impact.


130-130: Style fix in function signature
No concerns.


202-205: Graceful access of micr fields
Safer usage with .get() mitigates errors if keys are missing.


225-225: Potential KeyError on vendor email
Consider .get("email") or fallback logic.


246-250: Valid barcode extraction
Implementation looks correct and handles missing data gracefully.


255-255: Potential KeyError on iban
Handle missing iban key if necessary.


257-257: Local currency assignment
No issues noted.


263-267: Potential ValueError on integer conversion
Handle non-numeric strings if there's a chance of invalid input.


287-288: Using .get() to avoid KeyError
Good defensive practice.

edenai_apis/apis/replicate/replicate_api.py (3)

4-7: New imports for LLM support
No issues.


49-50: StdLLMEngine initialization
Consistent with other classes.


245-321: Avoid using mutable default arguments
Similar B006 issue with messages: List = [].

-    def llm__chat(
-        self,
-        messages: List = [],
+    def llm__chat(
+        self,
+        messages: Optional[List] = None,
         ...
     ):
+        if messages is None:
+            messages = []
🧰 Tools
🪛 Ruff (0.8.2)

247-247: Do not use mutable data structures for argument defaults

Replace with None; initialize within function

(B006)

@@ -181,7 +180,12 @@ def test_tool_use(self, engine: LLMEngine):
"max_tokens": 1000,
"model": "gpt-3.5-turbo",
"mock_tool_calls": tool_calls,
"api_key": "opeizaopei"
"api_key": "opeizaopei",
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Avoid hardcoded API keys in test code.

Even for test code, hardcoded API keys are a security risk if accidentally committed to public repositories. Consider using environment variables, test fixtures, or mock constants instead.

-            "api_key": "opeizaopei",
+            "api_key": os.environ.get("TEST_API_KEY", "test_key"),

Make sure to import os at the top of the file if this approach is used.

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
"api_key": "opeizaopei",
import os # Make sure this is added at the top of the file if not already imported
# ... (other code)
"api_key": os.environ.get("TEST_API_KEY", "test_key"),
# ... (other code)

Comment on lines 12 to +14
@root_validator(pre=True)
def _set_prediction(cls, values: dict) -> dict:
plag_score = values.get('plagia_score', None)
plag_score = values.get("plagia_score", None)
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Verification agent

❓ Verification inconclusive

Migrate to Pydantic V2 Validator and Update Value Retrieval.
The validator defined on lines 12–14 uses the deprecated Pydantic V1 style (@root_validator(pre=True)). To ensure future compatibility, consider switching to the V2 style, for example using @model_validator(mode="before"). Moreover, static analysis suggests simplifying the value retrieval by removing the unnecessary default value (None). Use values.get("plagia_score") instead of values.get("plagia_score", None). You might apply the following diff:

-    @root_validator(pre=True)
-    def _set_prediction(cls, values: dict) -> dict:
-        plag_score = values.get("plagia_score", None)
+    @model_validator(mode="before")
+    def _set_prediction(cls, values: dict) -> dict:
+        plag_score = values.get("plagia_score")

Action: Update to Pydantic V2 Validator and Simplify Value Retrieval

  • Replace the Pydantic V1 style @root_validator(pre=True) with the new V2 style using @model_validator(mode="before").
  • Simplify the value lookup by removing the unnecessary default, using values.get("plagia_score") instead of values.get("plagia_score", None).
-    @root_validator(pre=True)
-    def _set_prediction(cls, values: dict) -> dict:
-        plag_score = values.get("plagia_score", None)
+    @model_validator(mode="before")
+    def _set_prediction(cls, values: dict) -> dict:
+        plag_score = values.get("plagia_score")

These updates ensure the code aligns with Pydantic V2 conventions and improves clarity.

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
@root_validator(pre=True)
def _set_prediction(cls, values: dict) -> dict:
plag_score = values.get('plagia_score', None)
plag_score = values.get("plagia_score", None)
@model_validator(mode="before")
def _set_prediction(cls, values: dict) -> dict:
plag_score = values.get("plagia_score")
🧰 Tools
🪛 Ruff (0.8.2)

14-14: Use values.get("plagia_score") instead of values.get("plagia_score", None)

Replace values.get("plagia_score", None) with values.get("plagia_score")

(SIM910)

🪛 GitHub Actions: CICD

[warning] 12-12: Pydantic V1 style @root_validator validators are deprecated. You should migrate to Pydantic V2 style @model_validator validators.

"hu-HU_Zoe Nagy": "63b408f0241a82001d51c518",
"pl-PL_Zuzanna Kackz": "63b409af241a82001d51c6ec",
"kn-IN_Aadesh Madar": "63b4094b241a82001d51c5fc",
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Duplicate Dictionary Key Warning

Static analysis highlights that the dictionary key literal "kn-IN_Aadesh Madar" appears more than once in the voice_ids dictionary. Duplicated keys in a Python dictionary will result in only the last occurrence being retained. Please remove or correct the duplicate key to ensure that each voice identifier is unique and intentional.

🧰 Tools
🪛 Ruff (0.8.2)

242-242: Dictionary key literal "kn-IN_Aadesh Madar" repeated

Remove repeated key literal "kn-IN_Aadesh Madar"

(F601)


def llm__chat(
self,
messages: List = [],
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Fix the mutable default argument for messages.

Using a mutable default value (empty list) can cause unexpected behavior when the function is called multiple times.

-    def llm__chat(
-        self,
-        messages: List = [],
+    def llm__chat(
+        self,
+        messages: Optional[List] = None,

Add initialization inside the function:

     def llm__chat(
         self,
-        messages: List = [],
+        messages: Optional[List] = None,
         model: Optional[str] = None,
         ...
     ) -> ChatCompletionResponse:
+        if messages is None:
+            messages = []
         response = self.std_llm_client.completion(
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
messages: List = [],
def llm__chat(
self,
messages: Optional[List] = None,
model: Optional[str] = None,
...
) -> ChatCompletionResponse:
if messages is None:
messages = []
response = self.std_llm_client.completion(
🧰 Tools
🪛 Ruff (0.8.2)

142-142: Do not use mutable data structures for argument defaults

Replace with None; initialize within function

(B006)


import httpx
from openai import BaseModel
from apis.amazon.config import clients, storage_clients
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Fix circular import issue by using absolute import path.

The current relative import is causing a circular import error in the CI pipeline.

-from apis.amazon.config import clients, storage_clients
+from edenai_apis.apis.amazon.config import clients, storage_clients
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
from apis.amazon.config import clients, storage_clients
from edenai_apis.apis.amazon.config import clients, storage_clients
🧰 Tools
🪛 GitHub Actions: CICD

[error] 5-5: ImportError: cannot import name 'AmazonLLMApi' from partially initialized module 'edenai_apis.apis.amazon.amazon_llm_api' (most likely due to a circular import)


[error] 5-5: ImportError: cannot import name 'AmazonLLMApi' from partially initialized module 'edenai_apis.apis.amazon.amazon_llm_api' (most likely due to a circular import)

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

♻️ Duplicate comments (2)
edenai_apis/apis/amazon/amazon_llm_api.py (2)

5-5: ⚠️ Potential issue

Fix circular import issue by using absolute import path.

The current relative import is causing a circular import error in the CI pipeline.

-from apis.amazon.config import clients, storage_clients
+from edenai_apis.apis.amazon.config import clients, storage_clients
🧰 Tools
🪛 Ruff (0.8.2)

5-5: apis.amazon.config.clients imported but unused

Remove unused import

(F401)


5-5: apis.amazon.config.storage_clients imported but unused

Remove unused import

(F401)

🪛 GitHub Actions: CICD

[error] 5-5: ImportError: cannot import name 'AmazonLLMApi' from partially initialized module 'edenai_apis.apis.amazon.amazon_llm_api' (most likely due to a circular import)


17-17: ⚠️ Potential issue

Avoid mutable default for messages.

Using a list as a default parameter can cause shared state across function calls, leading to unexpected behavior.

-def llm__chat(
-    self,
-    messages: List = [],
+def llm__chat(
+    self,
+    messages: Optional[List] = None,

Then inside the function, add:

if messages is None:
    messages = []
🧰 Tools
🪛 Ruff (0.8.2)

17-17: Do not use mutable data structures for argument defaults

Replace with None; initialize within function

(B006)

🧹 Nitpick comments (4)
edenai_apis/apis/amazon/amazon_llm_api.py (4)

1-1: Fix unused imports.

Several imports are flagged as unused by the static analysis tools. While some might be used in the broader context, the Dict import appears to be completely unused in this file.

-from typing import Dict, List, Type, Union, Optional
+from typing import List, Type, Union, Optional
🧰 Tools
🪛 Ruff (0.8.2)

1-1: typing.Dict imported but unused

Remove unused import: typing.Dict

(F401)


27-27: Fix type hint for stop_sequences.

The type hint Optional[any] is not a standard Python type hint. Use Optional[Any] with a capital 'A' and import it from typing.

-from typing import List, Type, Union, Optional
+from typing import List, Type, Union, Optional, Any

# Then later in the code:
-        stop_sequences: Optional[any] = None,
+        stop_sequences: Optional[Any] = None,

42-42: Add type hint for deployment_id.

All other parameters have type hints except deployment_id. For consistency, add an appropriate type hint.

-        deployment_id=None,
+        deployment_id: Optional[str] = None,

19-55: Consider grouping related parameters for better readability.

The method has a large number of parameters which can make it hard to read and maintain. Consider grouping related parameters using a dataclass or dictionary to improve readability.

For example, you could create dataclasses for different parameter groups:

@dataclass
class OpenAIChatParams:
    temperature: Optional[float] = None
    top_p: Optional[float] = None
    # ...other OpenAI parameters

@dataclass
class AmazonChatParams:
    # Amazon-specific parameters

# Then in the method:
def llm__chat(
    self,
    messages: Optional[List] = None,
    model: Optional[str] = None,
    openai_params: Optional[OpenAIChatParams] = None,
    amazon_params: Optional[AmazonChatParams] = None,
    # ...other essential parameters
) -> ChatCompletionResponse:
    # Use the parameters from the dataclasses

This would make the method signature much cleaner while still allowing all the same functionality.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 211c813 and 6f7551e.

📒 Files selected for processing (2)
  • edenai_apis/apis/amazon/amazon_api.py (4 hunks)
  • edenai_apis/apis/amazon/amazon_llm_api.py (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • edenai_apis/apis/amazon/amazon_api.py
🧰 Additional context used
🪛 Ruff (0.8.2)
edenai_apis/apis/amazon/amazon_llm_api.py

1-1: typing.Dict imported but unused

Remove unused import: typing.Dict

(F401)


5-5: apis.amazon.config.clients imported but unused

Remove unused import

(F401)


5-5: apis.amazon.config.storage_clients imported but unused

Remove unused import

(F401)


7-7: edenai_apis.llmengine.llm_engine.StdLLMEngine imported but unused

Remove unused import: edenai_apis.llmengine.llm_engine.StdLLMEngine

(F401)


8-8: edenai_apis.loaders.data_loader.ProviderDataEnum imported but unused

Remove unused import: edenai_apis.loaders.data_loader.ProviderDataEnum

(F401)


9-9: edenai_apis.loaders.loaders.load_provider imported but unused

Remove unused import: edenai_apis.loaders.loaders.load_provider

(F401)


17-17: Do not use mutable data structures for argument defaults

Replace with None; initialize within function

(B006)

🪛 GitHub Actions: CICD
edenai_apis/apis/amazon/amazon_llm_api.py

[error] 5-5: ImportError: cannot import name 'AmazonLLMApi' from partially initialized module 'edenai_apis.apis.amazon.amazon_llm_api' (most likely due to a circular import)

Comment on lines 7 to 9
from edenai_apis.llmengine.llm_engine import StdLLMEngine
from edenai_apis.loaders.data_loader import ProviderDataEnum
from edenai_apis.loaders.loaders import load_provider
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Verification agent

🧩 Analysis chain

Verify usage of potentially unused imports.

These imports are flagged as unused by the static analysis tool. If they're not being used anywhere in this file, they should be removed.


🏁 Script executed:

#!/bin/bash
# Search for usage of these imported classes in the file
echo "Searching for usage of StdLLMEngine, ProviderDataEnum, and load_provider in amazon_llm_api.py"
rg -n "std_llm_client" "edenai_apis/apis/amazon/amazon_llm_api.py"
rg -n "StdLLMEngine" "edenai_apis/apis/amazon/amazon_llm_api.py"
rg -n "ProviderDataEnum" "edenai_apis/apis/amazon/amazon_llm_api.py"
rg -n "load_provider" "edenai_apis/apis/amazon/amazon_llm_api.py"

# Check if these are used in amazon_api.py where AmazonLLMApi might be used as a base class
echo "Checking if these classes are used in amazon_api.py"
rg -n "StdLLMEngine" "edenai_apis/apis/amazon/amazon_api.py"

Length of output: 979


Unused Imports in amazon_llm_api.py – Clean Up Recommended

  • The StdLLMEngine import is justified because its instance (referenced as std_llm_client) is used in the file.
  • However, both ProviderDataEnum and load_provider are only imported (lines 8–9) and show no usage in the file.

Please remove the unused ProviderDataEnum and load_provider imports to keep the code clean.

🧰 Tools
🪛 Ruff (0.8.2)

7-7: edenai_apis.llmengine.llm_engine.StdLLMEngine imported but unused

Remove unused import: edenai_apis.llmengine.llm_engine.StdLLMEngine

(F401)


8-8: edenai_apis.loaders.data_loader.ProviderDataEnum imported but unused

Remove unused import: edenai_apis.loaders.data_loader.ProviderDataEnum

(F401)


9-9: edenai_apis.loaders.loaders.load_provider imported but unused

Remove unused import: edenai_apis.loaders.loaders.load_provider

(F401)

Comment on lines +56 to +90
response = self.std_llm_client.completion(
messages=messages,
model=model,
timeout=timeout,
temperature=temperature,
top_p=top_p,
n=n,
stream=stream,
stream_options=stream_options,
stop=stop,
stop_sequences=stop_sequences,
max_tokens=max_tokens,
presence_penalty=presence_penalty,
frequency_penalty=frequency_penalty,
logit_bias=logit_bias,
response_format=response_format,
seed=seed,
tools=tools,
tool_choice=tool_choice,
logprobs=logprobs,
top_logprobs=top_logprobs,
parallel_tool_calls=parallel_tool_calls,
deployment_id=deployment_id,
extra_headers=extra_headers,
functions=functions,
function_call=function_call,
base_url=base_url,
api_version=api_version,
api_key=api_key,
model_list=model_list,
drop_invalid_params=drop_invalid_params,
user=user,
**kwargs,
)
return response
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Ensure proper error handling for the API call.

The method delegates to self.std_llm_client.completion() but doesn't include any error handling for potential API failures or exceptions. Consider adding appropriate try-except blocks to gracefully handle errors.

 def llm__chat(
     # ...parameters...
 ) -> ChatCompletionResponse:
-    response = self.std_llm_client.completion(
-        messages=messages,
-        model=model,
-        # ...other parameters...
-        **kwargs,
-    )
-    return response
+    try:
+        response = self.std_llm_client.completion(
+            messages=messages,
+            model=model,
+            # ...other parameters...
+            **kwargs,
+        )
+        return response
+    except Exception as e:
+        # Handle the error appropriately, possibly logging it
+        # and then either re-raise or return a suitable error response
+        raise
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
response = self.std_llm_client.completion(
messages=messages,
model=model,
timeout=timeout,
temperature=temperature,
top_p=top_p,
n=n,
stream=stream,
stream_options=stream_options,
stop=stop,
stop_sequences=stop_sequences,
max_tokens=max_tokens,
presence_penalty=presence_penalty,
frequency_penalty=frequency_penalty,
logit_bias=logit_bias,
response_format=response_format,
seed=seed,
tools=tools,
tool_choice=tool_choice,
logprobs=logprobs,
top_logprobs=top_logprobs,
parallel_tool_calls=parallel_tool_calls,
deployment_id=deployment_id,
extra_headers=extra_headers,
functions=functions,
function_call=function_call,
base_url=base_url,
api_version=api_version,
api_key=api_key,
model_list=model_list,
drop_invalid_params=drop_invalid_params,
user=user,
**kwargs,
)
return response
try:
response = self.std_llm_client.completion(
messages=messages,
model=model,
timeout=timeout,
temperature=temperature,
top_p=top_p,
n=n,
stream=stream,
stream_options=stream_options,
stop=stop,
stop_sequences=stop_sequences,
max_tokens=max_tokens,
presence_penalty=presence_penalty,
frequency_penalty=frequency_penalty,
logit_bias=logit_bias,
response_format=response_format,
seed=seed,
tools=tools,
tool_choice=tool_choice,
logprobs=logprobs,
top_logprobs=top_logprobs,
parallel_tool_calls=parallel_tool_calls,
deployment_id=deployment_id,
extra_headers=extra_headers,
functions=functions,
function_call=function_call,
base_url=base_url,
api_version=api_version,
api_key=api_key,
model_list=model_list,
drop_invalid_params=drop_invalid_params,
user=user,
**kwargs,
)
return response
except Exception as e:
# Handle the error appropriately, possibly logging it
# and then either re-raise or return a suitable error response
raise

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

♻️ Duplicate comments (5)
edenai_apis/apis/xai/xai_llm_api.py (1)

11-13: ⚠️ Potential issue

Fix mutable default argument risk

Using mutable objects like empty lists as default arguments can lead to unexpected behavior when the function is called multiple times. The default value is created once at function definition time and reused for all calls.

Apply this fix to use None instead and initialize within the function:

-    def llm__chat(
-        self,
-        messages: List = [],
+    def llm__chat(
+        self,
+        messages: Optional[List] = None,

Then add this check at the beginning of the method:

if messages is None:
    messages = []
🧰 Tools
🪛 Ruff (0.8.2)

13-13: Do not use mutable data structures for argument defaults

Replace with None; initialize within function

(B006)

edenai_apis/apis/amazon/amazon_llm_api.py (2)

11-13: ⚠️ Potential issue

Fix mutable default argument risk

Using mutable objects like empty lists as default arguments can lead to unexpected behavior when the function is called multiple times. The default value is created once at function definition time and reused for all calls.

Apply this fix to use None instead and initialize within the function:

-    def llm__chat(
-        self,
-        messages: List = [],
+    def llm__chat(
+        self,
+        messages: Optional[List] = None,

Then add this check at the beginning of the method:

if messages is None:
    messages = []
🧰 Tools
🪛 Ruff (0.8.2)

13-13: Do not use mutable data structures for argument defaults

Replace with None; initialize within function

(B006)


52-86: 🛠️ Refactor suggestion

Add error handling for API calls

The method forwards the request to self.std_llm_client.completion() but lacks error handling for potential API failures or timeouts.

Implement proper error handling:

-    response = self.std_llm_client.completion(
-        messages=messages,
-        model=model,
-        timeout=timeout,
-        # ...other parameters
-        **kwargs,
-    )
-    return response
+    try:
+        response = self.std_llm_client.completion(
+            messages=messages,
+            model=model,
+            timeout=timeout,
+            # ...other parameters
+            **kwargs,
+        )
+        return response
+    except Exception as e:
+        # Consider logging the error
+        # Optionally transform to a more specific exception
+        raise
edenai_apis/apis/cohere/cohere_api.py (2)

334-336: ⚠️ Potential issue

Fix mutable default argument risk

Using mutable objects like empty lists as default arguments can lead to unexpected behavior when the function is called multiple times. The default value is created once at function definition time and reused for all calls.

Apply this fix to use None instead and initialize within the function:

-    def llm__chat(
-        self,
-        messages: List = [],
+    def llm__chat(
+        self,
+        messages: Optional[List] = None,

Then add this check at the beginning of the method:

if messages is None:
    messages = []
🧰 Tools
🪛 Ruff (0.8.2)

336-336: Do not use mutable data structures for argument defaults

Replace with None; initialize within function

(B006)


375-409: 🛠️ Refactor suggestion

Add error handling for API calls

The method forwards the request to self.std_llm_client.completion() but lacks error handling for potential API failures or timeouts.

Implement proper error handling:

-    response = self.std_llm_client.completion(
-        messages=messages,
-        model=model,
-        timeout=timeout,
-        # ...other parameters
-        **kwargs,
-    )
-    return response
+    try:
+        response = self.std_llm_client.completion(
+            messages=messages,
+            model=model,
+            timeout=timeout,
+            # ...other parameters
+            **kwargs,
+        )
+        return response
+    except Exception as e:
+        # Consider logging the error
+        # Optionally transform to a more specific exception
+        raise
🧹 Nitpick comments (3)
edenai_apis/apis/xai/xai_llm_api.py (1)

11-51: Consider documenting parameter types and requirements

The method has many parameters with minimal documentation about their expected types, ranges, or requirements. Adding detailed docstrings would improve code maintainability.

Add a comprehensive docstring like:

 def llm__chat(
     self,
     messages: List = [],
     model: Optional[str] = None,
     # Optional OpenAI params: see https://platform.openai.com/docs/api-reference/chat/create
     timeout: Optional[Union[float, str, httpx.Timeout]] = None,
     ...
 ) -> ChatCompletionResponse:
+    """Perform a chat completion request with a language model
+    
+    Args:
+        messages: List of message objects with 'role' and 'content' keys
+        model: Language model to use (provider-specific)
+        timeout: Request timeout in seconds or as httpx.Timeout object
+        temperature: Controls randomness (0-1), lower is more deterministic
+        ...
+        
+    Returns:
+        ChatCompletionResponse object containing model's response
+        
+    Raises:
+        Exception: If the completion request fails
+    """
🧰 Tools
🪛 Ruff (0.8.2)

13-13: Do not use mutable data structures for argument defaults

Replace with None; initialize within function

(B006)

edenai_apis/apis/amazon/amazon_llm_api.py (1)

1-1: Remove unused import

The Dict import is not used anywhere in this file.

-from typing import Dict, List, Type, Union, Optional
+from typing import List, Type, Union, Optional
🧰 Tools
🪛 Ruff (0.8.2)

1-1: typing.Dict imported but unused

Remove unused import: typing.Dict

(F401)

edenai_apis/apis/cohere/cohere_api.py (1)

334-373: Document API compatibility and usage notes

Given this PR is specifically about making the Eden AI chat API compatible with OpenAI, adding documentation about the compatibility aspects would be helpful.

Add a docstring that explains the OpenAI compatibility:

 def llm__chat(
     self,
     messages: List = [],
     model: Optional[str] = None,
     # Optional OpenAI params: see https://platform.openai.com/docs/api-reference/chat/create
     ...
 ) -> ChatCompletionResponse:
+    """
+    OpenAI-compatible chat completion endpoint for Cohere models.
+    
+    This method aims to provide a compatible interface with OpenAI's chat completion,
+    allowing for easier migration between providers. Parameters match those of OpenAI's
+    chat completion API where applicable, with additional Cohere-specific parameters.
+    
+    Note: Some parameters may not be supported by Cohere and will be ignored if
+    drop_invalid_params is True.
+    """
🧰 Tools
🪛 Ruff (0.8.2)

336-336: Do not use mutable data structures for argument defaults

Replace with None; initialize within function

(B006)

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 6f7551e and dc2c1c6.

📒 Files selected for processing (3)
  • edenai_apis/apis/amazon/amazon_llm_api.py (1 hunks)
  • edenai_apis/apis/cohere/cohere_api.py (4 hunks)
  • edenai_apis/apis/xai/xai_llm_api.py (1 hunks)
🧰 Additional context used
🪛 Ruff (0.8.2)
edenai_apis/apis/xai/xai_llm_api.py

13-13: Do not use mutable data structures for argument defaults

Replace with None; initialize within function

(B006)

edenai_apis/apis/cohere/cohere_api.py

336-336: Do not use mutable data structures for argument defaults

Replace with None; initialize within function

(B006)

edenai_apis/apis/amazon/amazon_llm_api.py

1-1: typing.Dict imported but unused

Remove unused import: typing.Dict

(F401)


13-13: Do not use mutable data structures for argument defaults

Replace with None; initialize within function

(B006)

⏰ Context from checks skipped due to timeout of 90000ms (1)
  • GitHub Check: test
🔇 Additional comments (4)
edenai_apis/apis/amazon/amazon_llm_api.py (1)

9-10: Ensure proper initialization of std_llm_client

The class uses self.std_llm_client in the llm__chat method, but there's no initialization in this class.

Verify that the attribute is properly initialized by a parent class or add an __init__ method:

#!/bin/bash
# Check how this class is used in the codebase
rg -n "AmazonLLMApi" "edenai_apis/"

# Check for initialization patterns in related files
rg -n "std_llm_client\s*=" "edenai_apis/apis/amazon/"
edenai_apis/apis/cohere/cohere_api.py (3)

35-35: LGTM! Interface implementation correctly added

The class now properly implements the LlmInterface alongside its existing interfaces.


54-54: LGTM! Correct initialization of std_llm_client

The StdLLMEngine is properly initialized in the constructor with the API key.


305-332:

❓ Verification inconclusive

Clarify the distinction between text__chat and llm__chat

The class now has two chat methods: text__chat and llm__chat. The distinction between these methods may not be clear to users.

Clarify whether both methods are needed and their differences. Consider adding comments or documentation to explain when to use each method:

Also applies to: 334-409


🌐 Web query:

What is the difference between OpenAI's chat API and standard text completion API?

💡 Result:

OpenAI's Chat API and standard text completion API serve different purposes in text generation, with key distinctions in structure, capabilities, and use cases:

Input Structure

  • Chat API
    Uses a structured message format with system, user, and assistant roles[1][8]. Example request:

    messages = [
        {"role": "system", "content": "You are a helpful assistant"},
        {"role": "user", "content": "Explain quantum computing"}
    ]

    This role-based structure helps separate instructions from user input[1].

  • Text Completion API
    Uses a single freeform prompt without role differentiation[3][8]:

    prompt = "As Descartes said, I think, therefore"

Conversation Handling

  • Chat API

    • Built for multi-turn dialogues[1][4]
    • Maintains conversation context automatically[5]
    • Supports streaming for real-time interactions[2]
  • Text Completion

    • Designed for single-prompt completions[8]
    • Requires manual context management for conversations[3]

Model Support & Features

  • Chat API

    • Accesses latest models (GPT-4o, GPT-4 Turbo)[3][9]
    • Supports multimodal inputs (text+images)[9]
    • Enables function calling for API integrations[4]
  • Text Completion

    • Limited to older models (GPT-3 series)[3]
    • Text-only interactions[8]

Security & Control

The Chat API reduces prompt injection risks through:

  1. Structural separation of system instructions and user content[1]
  2. Built-in conversation history management[5]
  3. Fine-grained moderation controls[2]

Usage Recommendations

  • Use Chat API for

    • Conversational applications[4][5]
    • Complex tasks requiring context[1]
    • Latest model capabilities[9]
  • Text Completion remains viable for

    • Simple text continuation tasks[8]
    • Legacy system integrations[3]

Most developers (97% of API usage) now prefer the Chat API due to its structured approach and advanced features[1]. While the completion endpoint still functions, OpenAI recommends new implementations use Chat Completions unless requiring specific legacy model behavior[3][8].

Citations:


Action: Enhance Documentation for Chat Methods Distinction

Please update the documentation and inline comments to clearly explain the differences between the two chat methods in this class. Currently, both text__chat (lines 305–332) and llm__chat (lines 334–409) delegate to the underlying chat client, but it isn’t clear under which circumstances each should be used. For example:

  • text__chat

    • Intended for scenarios where a simple text prompt is provided.
    • Mimics the behavior of a text completion API where the input is a single freeform string.
  • llm__chat

    • Likely designed for use cases requiring structured conversation context or multi-turn dialogue.
    • Its design may align more closely with modern chat APIs that use role-based messaging (as seen in OpenAI's Chat API).

Based on standard practices (e.g., OpenAI’s differentiation between chat and text completion APIs), consider adding comments or updating the API docs to specify:

  • The expected input format (single text vs. structured message arrays).
  • Use cases and benefits for each method.
  • Any differences in model support or conversation handling (for example, auto-maintained context in chats).

This clarification will reduce confusion for users regarding when to call text__chat versus llm__chat.

Comment on lines 9 to 51
class XAiLLMApi(LlmInterface):

def llm__chat(
self,
messages: List = [],
model: Optional[str] = None,
# Optional OpenAI params: see https://platform.openai.com/docs/api-reference/chat/create
timeout: Optional[Union[float, str, httpx.Timeout]] = None,
temperature: Optional[float] = None,
top_p: Optional[float] = None,
n: Optional[int] = None,
stream: Optional[bool] = None,
stream_options: Optional[dict] = None,
stop: Optional[str] = None,
stop_sequences: Optional[any] = None,
max_tokens: Optional[int] = None,
presence_penalty: Optional[float] = None,
frequency_penalty: Optional[float] = None,
logit_bias: Optional[dict] = None,
# openai v1.0+ new params
response_format: Optional[
Union[dict, Type[BaseModel]]
] = None, # Structured outputs
seed: Optional[int] = None,
tools: Optional[List] = None,
tool_choice: Optional[Union[str, dict]] = None,
logprobs: Optional[bool] = None,
top_logprobs: Optional[int] = None,
parallel_tool_calls: Optional[bool] = None,
deployment_id=None,
extra_headers: Optional[dict] = None,
# soon to be deprecated params by OpenAI -> This should be replaced by tools
functions: Optional[List] = None,
function_call: Optional[str] = None,
base_url: Optional[str] = None,
api_version: Optional[str] = None,
api_key: Optional[str] = None,
model_list: Optional[list] = None, # pass in a list of api_base,keys, etc.
drop_invalid_params: bool = True, # If true, all the invalid parameters will be ignored (dropped) before sending to the model
user: str | None = None,
# Optional parameters
**kwargs,
) -> ChatCompletionResponse:
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Verification agent

🧩 Analysis chain

Ensure proper initialization of std_llm_client

The class uses self.std_llm_client in the llm__chat method, but there's no visible initialization in the class.

Verify that the attribute is properly initialized by a parent class or add an __init__ method:


🏁 Script executed:

#!/bin/bash
# Check if the LlmInterface initializes std_llm_client
rg -n "std_llm_client\s*=" "edenai_apis/features/llm/llm_interface.py"

# Check if the class is used elsewhere and initialized properly
rg -n "XAiLLMApi" "edenai_apis/"

# Check if there are similar patterns in other API classes
rg -n "class \w+LLMApi.*LlmInterface" "edenai_apis/"

Length of output: 732


Ensure std_llm_client Is Properly Initialized

It appears that std_llm_client is used in the llm__chat method of XAiLLMApi but neither the parent class (LlmInterface) nor XAiLLMApi itself shows evidence of initializing this attribute. To prevent runtime issues, please verify that std_llm_client is correctly set up. For example, you may need to add an explicit __init__ to XAiLLMApi (or ensure it’s initialized in LlmInterface), such as:

class XAiLLMApi(LlmInterface):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.std_llm_client = initialize_std_llm_client()  # Add proper initialization here
  • Confirm whether the initialization should occur in the parent or the child class.
  • Update the code accordingly to ensure that std_llm_client is available before it’s used in llm__chat.
🧰 Tools
🪛 Ruff (0.8.2)

13-13: Do not use mutable data structures for argument defaults

Replace with None; initialize within function

(B006)

Comment on lines +52 to +86
response = self.std_llm_client.completion(
messages=messages,
model=model,
timeout=timeout,
temperature=temperature,
top_p=top_p,
n=n,
stream=stream,
stream_options=stream_options,
stop=stop,
stop_sequences=stop_sequences,
max_tokens=max_tokens,
presence_penalty=presence_penalty,
frequency_penalty=frequency_penalty,
logit_bias=logit_bias,
response_format=response_format,
seed=seed,
tools=tools,
tool_choice=tool_choice,
logprobs=logprobs,
top_logprobs=top_logprobs,
parallel_tool_calls=parallel_tool_calls,
deployment_id=deployment_id,
extra_headers=extra_headers,
functions=functions,
function_call=function_call,
base_url=base_url,
api_version=api_version,
api_key=api_key,
model_list=model_list,
drop_invalid_params=drop_invalid_params,
user=user,
**kwargs,
)
return response
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Add error handling for API calls

The method forwards the request to self.std_llm_client.completion() but lacks error handling for potential API failures or timeouts.

Implement proper error handling:

-    response = self.std_llm_client.completion(
-        messages=messages,
-        model=model,
-        timeout=timeout,
-        # ...other parameters
-        **kwargs,
-    )
-    return response
+    try:
+        response = self.std_llm_client.completion(
+            messages=messages,
+            model=model,
+            timeout=timeout,
+            # ...other parameters
+            **kwargs,
+        )
+        return response
+    except Exception as e:
+        # Consider logging the error
+        # Optionally transform to a more specific exception
+        raise
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
response = self.std_llm_client.completion(
messages=messages,
model=model,
timeout=timeout,
temperature=temperature,
top_p=top_p,
n=n,
stream=stream,
stream_options=stream_options,
stop=stop,
stop_sequences=stop_sequences,
max_tokens=max_tokens,
presence_penalty=presence_penalty,
frequency_penalty=frequency_penalty,
logit_bias=logit_bias,
response_format=response_format,
seed=seed,
tools=tools,
tool_choice=tool_choice,
logprobs=logprobs,
top_logprobs=top_logprobs,
parallel_tool_calls=parallel_tool_calls,
deployment_id=deployment_id,
extra_headers=extra_headers,
functions=functions,
function_call=function_call,
base_url=base_url,
api_version=api_version,
api_key=api_key,
model_list=model_list,
drop_invalid_params=drop_invalid_params,
user=user,
**kwargs,
)
return response
try:
response = self.std_llm_client.completion(
messages=messages,
model=model,
timeout=timeout,
temperature=temperature,
top_p=top_p,
n=n,
stream=stream,
stream_options=stream_options,
stop=stop,
stop_sequences=stop_sequences,
max_tokens=max_tokens,
presence_penalty=presence_penalty,
frequency_penalty=frequency_penalty,
logit_bias=logit_bias,
response_format=response_format,
seed=seed,
tools=tools,
tool_choice=tool_choice,
logprobs=logprobs,
top_logprobs=top_logprobs,
parallel_tool_calls=parallel_tool_calls,
deployment_id=deployment_id,
extra_headers=extra_headers,
functions=functions,
function_call=function_call,
base_url=base_url,
api_version=api_version,
api_key=api_key,
model_list=model_list,
drop_invalid_params=drop_invalid_params,
user=user,
**kwargs,
)
return response
except Exception as e:
# Consider logging the error
# Optionally transform to a more specific exception
raise

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 14

♻️ Duplicate comments (7)
edenai_apis/apis/openai/openai_llm_api.py (1)

11-14: ⚠️ Potential issue

Fix mutable default argument and improve type annotation.

Using a mutable object like an empty list as a default argument can lead to unexpected behavior. The list is created once at function definition time and shared across all calls, which can cause bugs if the list is modified.

 def llm__chat(
     self,
-    messages: List = [],
+    messages: List[dict] = None,
     model: Optional[str] = None,

Then add this initialization inside the function:

def llm__chat(self, messages: List[dict] = None, ...):
    if messages is None:
        messages = []
    # rest of function
🧰 Tools
🪛 Ruff (0.8.2)

13-13: Do not use mutable data structures for argument defaults

Replace with None; initialize within function

(B006)

edenai_apis/apis/xai/xai_llm_api.py (1)

11-14: ⚠️ Potential issue

Fix mutable default argument and improve type annotation.

Using a mutable object like an empty list as a default argument can lead to unexpected behavior. The list is created once at function definition time and shared across all calls, which can cause bugs if the list is modified.

 def llm__chat(
     self,
-    messages: List = [],
+    messages: List[dict] = None,
     model: Optional[str] = None,

Then add this initialization inside the function:

def llm__chat(self, messages: List[dict] = None, ...):
    if messages is None:
        messages = []
    # rest of function
🧰 Tools
🪛 Ruff (0.8.2)

13-13: Do not use mutable data structures for argument defaults

Replace with None; initialize within function

(B006)

edenai_apis/features/llm/llm_interface.py (1)

14-15: ⚠️ Potential issue

Fix mutable default argument and improve type annotation.

Using a mutable object like an empty list as a default argument can lead to unexpected behavior. The list is created once at function definition time and shared across all calls, which can cause bugs if the list is modified.

 def llm__chat(
     self,
-    messages: List = [],
+    messages: Optional[List[dict]] = None,
     model: Optional[str] = None,
🧰 Tools
🪛 Ruff (0.8.2)

15-15: Do not use mutable data structures for argument defaults

Replace with None; initialize within function

(B006)

edenai_apis/apis/cohere/cohere_api.py (1)

334-374: 🛠️ Refactor suggestion

Avoid mutable default argument and improve parameter typing.

Using a mutable object (empty list) as a default parameter value is a Python anti-pattern that can lead to unexpected behavior where the default list may be shared across function calls.

Fix by using None as the default and initializing an empty list inside the function:

- def llm__chat(
-     self,
-     messages: List = [],
+ def llm__chat(
+     self,
+     messages: Optional[List[Dict[str, Any]]] = None,
      ...
):
+     if messages is None:
+         messages = []

Also, the generic List type hint doesn't specify what elements the list contains. It would be more informative to use a more specific type hint like List[Dict[str, Any]] or create a dedicated type for message objects.

🧰 Tools
🪛 Ruff (0.8.2)

336-336: Do not use mutable data structures for argument defaults

Replace with None; initialize within function

(B006)

edenai_apis/apis/deepseek/deepseek_api.py (1)

62-102: 🛠️ Refactor suggestion

Avoid mutable default argument and improve parameter typing.

Using a mutable object (empty list) as a default parameter value is a Python anti-pattern that can lead to unexpected behavior where the default list may be shared across function calls.

Fix by using None as the default and initializing an empty list inside the function:

- def llm__chat(
-     self,
-     messages: List = [],
+ def llm__chat(
+     self,
+     messages: Optional[List[Dict[str, Any]]] = None,
      ...
):
+     if messages is None:
+         messages = []

Also, the generic List type hint doesn't specify what elements the list contains. It would be more informative to use a more specific type hint like List[Dict[str, Any]] or create a dedicated type for message objects.

🧰 Tools
🪛 Ruff (0.8.2)

64-64: Do not use mutable data structures for argument defaults

Replace with None; initialize within function

(B006)

edenai_apis/apis/mistral/mistral_api.py (1)

155-195: 🛠️ Refactor suggestion

Avoid mutable default argument and improve parameter typing.

Using a mutable object (empty list) as a default parameter value is a Python anti-pattern that can lead to unexpected behavior where the default list may be shared across function calls.

Fix by using None as the default and initializing an empty list inside the function:

- def llm__chat(
-     self,
-     messages: List = [],
+ def llm__chat(
+     self,
+     messages: Optional[List[Dict[str, Any]]] = None,
      ...
):
+     if messages is None:
+         messages = []

Also, the generic List type hint doesn't specify what elements the list contains. It would be more informative to use a more specific type hint like List[Dict[str, Any]] or create a dedicated type for message objects.

🧰 Tools
🪛 Ruff (0.8.2)

157-157: Do not use mutable data structures for argument defaults

Replace with None; initialize within function

(B006)

edenai_apis/apis/meta/meta_api.py (1)

134-174: 🛠️ Refactor suggestion

Avoid mutable default argument and improve parameter typing.

Using a mutable object (empty list) as a default parameter value is a Python anti-pattern that can lead to unexpected behavior where the default list may be shared across function calls.

Fix by using None as the default and initializing an empty list inside the function:

- def llm__chat(
-     self,
-     messages: List = [],
+ def llm__chat(
+     self,
+     messages: Optional[List[Dict[str, Any]]] = None,
      ...
):
+     if messages is None:
+         messages = []

Also, the generic List type hint doesn't specify what elements the list contains. It would be more informative to use a more specific type hint like List[Dict[str, Any]] or create a dedicated type for message objects.

🧰 Tools
🪛 Ruff (0.8.2)

136-136: Do not use mutable data structures for argument defaults

Replace with None; initialize within function

(B006)

🧹 Nitpick comments (17)
edenai_apis/apis/openai/openai_llm_api.py (2)

1-1: Remove unused import Dict.

The Dict type is imported but not used in this file.

-from typing import Dict, List, Type, Union, Optional
+from typing import List, Type, Union, Optional
🧰 Tools
🪛 Ruff (0.8.2)

1-1: typing.Dict imported but unused

Remove unused import: typing.Dict

(F401)


3-4: Remove unused OpenAI imports.

The OpenAI client and NOT_GIVEN constant are imported but not used in this file.

-from openai import BaseModel, OpenAI
-from openai import NOT_GIVEN
+from openai import BaseModel
🧰 Tools
🪛 Ruff (0.8.2)

3-3: openai.OpenAI imported but unused

Remove unused import: openai.OpenAI

(F401)


4-4: openai.NOT_GIVEN imported but unused

Remove unused import: openai.NOT_GIVEN

(F401)

edenai_apis/features/llm/chat/__init__.py (1)

1-15: Add __all__ to explicitly define exported symbols.

This __init__.py file imports many symbols but doesn't explicitly define which ones are meant to be re-exported. Adding an __all__ list would make the module's public API clearer.

 from .chat_args import chat_arguments
 from .chat_dataclass import (
     ChatCompletionChoice,
     ChatCompletionModel,
     ChatCompletionRequest,
     ChatMessage,
     ResponseFormat,
     ChatDataClass,
     ChatCompletionUsage,
     FunctionDefinition,
     ChatRole,
     ToolCall,
     ToolCallFunction,
     ToolDefinition,
 )
+
+__all__ = [
+    'chat_arguments',
+    'ChatCompletionChoice',
+    'ChatCompletionModel',
+    'ChatCompletionRequest',
+    'ChatMessage',
+    'ResponseFormat',
+    'ChatDataClass',
+    'ChatCompletionUsage',
+    'FunctionDefinition',
+    'ChatRole',
+    'ToolCall',
+    'ToolCallFunction',
+    'ToolDefinition',
+]
🧰 Tools
🪛 Ruff (0.8.2)

1-1: .chat_args.chat_arguments imported but unused; consider removing, adding to __all__, or using a redundant alias

(F401)


3-3: .chat_dataclass.ChatCompletionChoice imported but unused; consider removing, adding to __all__, or using a redundant alias

(F401)


4-4: .chat_dataclass.ChatCompletionModel imported but unused; consider removing, adding to __all__, or using a redundant alias

(F401)


5-5: .chat_dataclass.ChatCompletionRequest imported but unused; consider removing, adding to __all__, or using a redundant alias

(F401)


6-6: .chat_dataclass.ChatMessage imported but unused; consider removing, adding to __all__, or using a redundant alias

(F401)


7-7: .chat_dataclass.ResponseFormat imported but unused; consider removing, adding to __all__, or using a redundant alias

(F401)


8-8: .chat_dataclass.ChatDataClass imported but unused; consider removing, adding to __all__, or using a redundant alias

(F401)


9-9: .chat_dataclass.ChatCompletionUsage imported but unused; consider removing, adding to __all__, or using a redundant alias

(F401)


10-10: .chat_dataclass.FunctionDefinition imported but unused; consider removing, adding to __all__, or using a redundant alias

(F401)


11-11: .chat_dataclass.ChatRole imported but unused; consider removing, adding to __all__, or using a redundant alias

(F401)


12-12: .chat_dataclass.ToolCall imported but unused; consider removing, adding to __all__, or using a redundant alias

(F401)


13-13: .chat_dataclass.ToolCallFunction imported but unused; consider removing, adding to __all__, or using a redundant alias

(F401)


14-14: .chat_dataclass.ToolDefinition imported but unused; consider removing, adding to __all__, or using a redundant alias

(F401)

edenai_apis/features/llm/llm_interface.py (2)

2-2: Remove unused import Dict.

The Dict type is imported but not used in this file.

-from typing import Optional, List, Dict, Type, Union
+from typing import Optional, List, Type, Union
🧰 Tools
🪛 Ruff (0.8.2)

2-2: typing.Dict imported but unused

Remove unused import: typing.Dict

(F401)


10-10: Consider initializing std_llm_client in the base interface.

The implementations of LlmInterface are using self.std_llm_client, but there's no initialization in this interface. To ensure consistent behavior across implementations, consider adding an __init__ method in this interface to initialize the client.

 class LlmInterface:
+    def __init__(self, *args, **kwargs):
+        super().__init__(*args, **kwargs)
+        self.std_llm_client = None  # Or initialize with an appropriate client
 
     @abstractmethod
     def llm__chat(
edenai_apis/apis/amazon/amazon_llm_api.py (1)

1-1: Unused import should be removed.

The Dict type is imported on this line but not used anywhere in the file.

-from typing import Dict, List, Type, Union, Optional
+from typing import List, Type, Union, Optional
🧰 Tools
🪛 Ruff (0.8.2)

1-1: typing.Dict imported but unused

Remove unused import: typing.Dict

(F401)

edenai_apis/apis/google/google_llm_api.py (1)

52-52: Inconsistent client access pattern across providers.

This implementation accesses the client through self.clients["std_llm_client"] while other providers (Amazon, Together.ai) use a direct attribute self.std_llm_client.

Either standardize all providers to use the same access pattern or ensure there's a clear reason for the difference in implementation.

-        response = self.clients["std_llm_client"].completion(
+        response = self.std_llm_client.completion(

This would require changing the initialization pattern as well to match other providers.

edenai_apis/apis/anthropic/anthropic_api.py (1)

44-49: Configuration duplication risk.

The std_llm_client is initialized with the same configuration as llm_client. Consider extracting this configuration to a variable to ensure they stay in sync if changes are needed in the future.

+        client_config = {
+            "api_key": self.api_settings.get("api_key"),
+            "cache_control": {"type": "ephemeral"},
+        }
         self.llm_client = LLMEngine(
             provider_name=self.provider_name,
-            provider_config={
-                "api_key": self.api_settings.get("api_key"),
-                "cache_control": {"type": "ephemeral"},
-            },
+            provider_config=client_config,
         )

         self.std_llm_client = StdLLMEngine(
-            provider_config={
-                "api_key": self.api_settings.get("api_key"),
-                "cache_control": {"type": "ephemeral"},
-            },
+            provider_config=client_config,
         )
edenai_apis/apis/cohere/cohere_api.py (1)

375-409: Good implementation of the method but consider adding error handling.

The implementation correctly passes all parameters to the std_llm_client.completion method and returns its response. However, there's no error handling if the completion call fails.

Consider adding error handling similar to other methods in this class:

def llm__chat(self, ...):
+    try:
         response = self.std_llm_client.completion(
             messages=messages,
             ...
         )
         return response
+    except Exception as e:
+        raise ProviderException(str(e))
edenai_apis/apis/deepseek/deepseek_api.py (1)

103-137: Good implementation of the method but consider adding error handling.

The implementation correctly passes all parameters to the std_llm_client.completion method and returns its response. However, there's no error handling if the completion call fails.

Consider adding error handling similar to other methods in this API class:

def llm__chat(self, ...):
+    try:
         response = self.std_llm_client.completion(
             messages=messages,
             ...
         )
         return response
+    except Exception as e:
+        raise ProviderException(str(e))
edenai_apis/apis/mistral/mistral_api.py (1)

196-230: Good implementation of the method but consider adding error handling.

The implementation correctly passes all parameters to the std_llm_client.completion method and returns its response. However, there's no error handling if the completion call fails.

Consider adding error handling similar to other methods in this API class, such as the error handling in the text__generation method:

def llm__chat(self, ...):
+    try:
         response = self.std_llm_client.completion(
             messages=messages,
             ...
         )
         return response
+    except Exception as e:
+        raise ProviderException(str(e))
edenai_apis/apis/meta/meta_api.py (1)

175-209: Good implementation of the method but consider adding error handling.

The implementation correctly passes all parameters to the std_llm_client.completion method and returns its response. However, there's no error handling if the completion call fails.

Consider adding error handling similar to the pattern used with handle_amazon_call in the text__generation method:

def llm__chat(self, ...):
+    try:
         response = self.std_llm_client.completion(
             messages=messages,
             ...
         )
         return response
+    except Exception as e:
+        # Consider using handle_amazon_call if applicable
+        raise ProviderException(str(e))
edenai_apis/apis/replicate/replicate_api.py (4)

7-7: Potential naming conflict with BaseModel.
In this file, BaseModel is imported from openai, whereas in other parts of the codebase, BaseModel is imported from pydantic. This could lead to confusion or unintentional usage of the wrong type. Consider renaming or aliasing if both are needed.


24-26: Avoid re-importing ChatDataClass.
ChatDataClass is already imported at line 17, which may conflict or cause confusion. Removing the duplicated import or aliasing can resolve this.

-from edenai_apis.features.text import (
-    ChatDataClass,
-)
...
-from edenai_apis.features.llm.chat.chat_dataclass import ChatDataClass
+# Remove one import if unused or alias distinct classes appropriately
🧰 Tools
🪛 Ruff (0.8.2)

26-26: Redefinition of unused ChatDataClass from line 17

(F811)


49-49: Consider unifying the LLM client usage.
The class already has self.llm_client = LLMEngine(...). Introducing self.std_llm_client might be duplicative and cause confusion. If both are needed for separate functionalities, clarify usage or naming.


245-319: Overall design of the llm__chat method looks solid.
The function provides an extensive parameter set to model a wide range of chat interactions. Consider adding docstrings clarifying parameter usage and expected behavior, especially around advanced or experimental parameters (e.g., drop_invalid_params).

🧰 Tools
🪛 Ruff (0.8.2)

247-247: Do not use mutable data structures for argument defaults

Replace with None; initialize within function

(B006)

edenai_apis/features/llm/chat/chat_dataclass.py (1)

62-125: ChatCompletionRequest captures advanced chat configuration.
The design is flexible for various LLM use cases. Suggest documenting or validating model thoroughly, especially when passing str versus ChatCompletionModel.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between dc2c1c6 and b759c0f.

📒 Files selected for processing (14)
  • edenai_apis/apis/amazon/amazon_llm_api.py (1 hunks)
  • edenai_apis/apis/anthropic/anthropic_api.py (4 hunks)
  • edenai_apis/apis/cohere/cohere_api.py (4 hunks)
  • edenai_apis/apis/deepseek/deepseek_api.py (4 hunks)
  • edenai_apis/apis/google/google_llm_api.py (1 hunks)
  • edenai_apis/apis/meta/meta_api.py (4 hunks)
  • edenai_apis/apis/mistral/mistral_api.py (4 hunks)
  • edenai_apis/apis/openai/openai_llm_api.py (1 hunks)
  • edenai_apis/apis/replicate/replicate_api.py (4 hunks)
  • edenai_apis/apis/together_ai/together_ai_api.py (4 hunks)
  • edenai_apis/apis/xai/xai_llm_api.py (1 hunks)
  • edenai_apis/features/llm/chat/__init__.py (1 hunks)
  • edenai_apis/features/llm/chat/chat_dataclass.py (1 hunks)
  • edenai_apis/features/llm/llm_interface.py (1 hunks)
🧰 Additional context used
🪛 Ruff (0.8.2)
edenai_apis/apis/amazon/amazon_llm_api.py

1-1: typing.Dict imported but unused

Remove unused import: typing.Dict

(F401)


13-13: Do not use mutable data structures for argument defaults

Replace with None; initialize within function

(B006)

edenai_apis/apis/cohere/cohere_api.py

32-32: Redefinition of unused ChatDataClass from line 9

(F811)


336-336: Do not use mutable data structures for argument defaults

Replace with None; initialize within function

(B006)

edenai_apis/apis/openai/openai_llm_api.py

1-1: typing.Dict imported but unused

Remove unused import: typing.Dict

(F401)


3-3: openai.OpenAI imported but unused

Remove unused import: openai.OpenAI

(F401)


4-4: openai.NOT_GIVEN imported but unused

Remove unused import: openai.NOT_GIVEN

(F401)


13-13: Do not use mutable data structures for argument defaults

Replace with None; initialize within function

(B006)

edenai_apis/apis/meta/meta_api.py

25-25: Redefinition of unused ChatDataClass from line 9

(F811)


136-136: Do not use mutable data structures for argument defaults

Replace with None; initialize within function

(B006)

edenai_apis/apis/xai/xai_llm_api.py

13-13: Do not use mutable data structures for argument defaults

Replace with None; initialize within function

(B006)

edenai_apis/apis/replicate/replicate_api.py

26-26: Redefinition of unused ChatDataClass from line 17

(F811)


247-247: Do not use mutable data structures for argument defaults

Replace with None; initialize within function

(B006)

edenai_apis/features/llm/llm_interface.py

2-2: typing.Dict imported but unused

Remove unused import: typing.Dict

(F401)


15-15: Do not use mutable data structures for argument defaults

Replace with None; initialize within function

(B006)

edenai_apis/apis/together_ai/together_ai_api.py

15-15: Redefinition of unused ChatDataClass from line 7

(F811)


69-69: Do not use mutable data structures for argument defaults

Replace with None; initialize within function

(B006)

edenai_apis/apis/deepseek/deepseek_api.py

16-16: Redefinition of unused ChatDataClass from line 6

(F811)


64-64: Do not use mutable data structures for argument defaults

Replace with None; initialize within function

(B006)

edenai_apis/apis/google/google_llm_api.py

13-13: Do not use mutable data structures for argument defaults

Replace with None; initialize within function

(B006)

edenai_apis/apis/anthropic/anthropic_api.py

26-26: Redefinition of unused ChatDataClass from line 20

(F811)


142-142: Do not use mutable data structures for argument defaults

Replace with None; initialize within function

(B006)

edenai_apis/apis/mistral/mistral_api.py

23-23: Redefinition of unused ChatDataClass from line 7

(F811)


157-157: Do not use mutable data structures for argument defaults

Replace with None; initialize within function

(B006)

edenai_apis/features/llm/chat/__init__.py

1-1: .chat_args.chat_arguments imported but unused; consider removing, adding to __all__, or using a redundant alias

(F401)


3-3: .chat_dataclass.ChatCompletionChoice imported but unused; consider removing, adding to __all__, or using a redundant alias

(F401)


4-4: .chat_dataclass.ChatCompletionModel imported but unused; consider removing, adding to __all__, or using a redundant alias

(F401)


5-5: .chat_dataclass.ChatCompletionRequest imported but unused; consider removing, adding to __all__, or using a redundant alias

(F401)


6-6: .chat_dataclass.ChatMessage imported but unused; consider removing, adding to __all__, or using a redundant alias

(F401)


7-7: .chat_dataclass.ResponseFormat imported but unused; consider removing, adding to __all__, or using a redundant alias

(F401)


8-8: .chat_dataclass.ChatDataClass imported but unused; consider removing, adding to __all__, or using a redundant alias

(F401)


9-9: .chat_dataclass.ChatCompletionUsage imported but unused; consider removing, adding to __all__, or using a redundant alias

(F401)


10-10: .chat_dataclass.FunctionDefinition imported but unused; consider removing, adding to __all__, or using a redundant alias

(F401)


11-11: .chat_dataclass.ChatRole imported but unused; consider removing, adding to __all__, or using a redundant alias

(F401)


12-12: .chat_dataclass.ToolCall imported but unused; consider removing, adding to __all__, or using a redundant alias

(F401)


13-13: .chat_dataclass.ToolCallFunction imported but unused; consider removing, adding to __all__, or using a redundant alias

(F401)


14-14: .chat_dataclass.ToolDefinition imported but unused; consider removing, adding to __all__, or using a redundant alias

(F401)

⏰ Context from checks skipped due to timeout of 90000ms (1)
  • GitHub Check: test
🔇 Additional comments (26)
edenai_apis/apis/openai/openai_llm_api.py (1)

52-86: Add error handling for API calls.

The method forwards the request to self.std_llm_client.completion() but lacks error handling for potential API failures or timeouts. This could lead to unhandled exceptions or obscure error messages.

-    response = self.std_llm_client.completion(
-        messages=messages,
-        model=model,
-        timeout=timeout,
-        # ...other parameters
-        **kwargs,
-    )
-    return response
+    try:
+        response = self.std_llm_client.completion(
+            messages=messages,
+            model=model,
+            timeout=timeout,
+            # ...other parameters
+            **kwargs,
+        )
+        return response
+    except Exception as e:
+        # Consider logging the error
+        # Optionally transform to a more specific exception
+        raise
edenai_apis/apis/xai/xai_llm_api.py (2)

9-10: Implement __init__ method to initialize std_llm_client.

The llm__chat method uses self.std_llm_client but there's no initialization in this class. This could lead to runtime errors if std_llm_client is not set by a parent class or elsewhere.

#!/bin/bash
# Check if std_llm_client is initialized in parent classes or in the `XAiApi` class
# Look for initialization in parent or related classes
echo "Checking for std_llm_client initialization in LlmInterface:"
rg -n "std_llm_client\s*=" "edenai_apis/features/llm/llm_interface.py"

echo -e "\nChecking for std_llm_client initialization in the XAiApi class:"
rg -n "std_llm_client\s*=" "edenai_apis/apis/xai/xai_api.py"

echo -e "\nChecking for the usage pattern in other LLM API classes:"
rg -n "class \w+API.*XAiLLMApi" -A 15 "edenai_apis/" | grep -E "def __init__|std_llm_client"

52-86: Add error handling for API calls.

The method forwards the request to self.std_llm_client.completion() but lacks error handling for potential API failures or timeouts. This could lead to unhandled exceptions or obscure error messages.

-    response = self.std_llm_client.completion(
-        messages=messages,
-        model=model,
-        timeout=timeout,
-        # ...other parameters
-        **kwargs,
-    )
-    return response
+    try:
+        response = self.std_llm_client.completion(
+            messages=messages,
+            model=model,
+            timeout=timeout,
+            # ...other parameters
+            **kwargs,
+        )
+        return response
+    except Exception as e:
+        # Consider logging the error
+        # Optionally transform to a more specific exception
+        raise
edenai_apis/apis/amazon/amazon_llm_api.py (2)

13-13: Fix mutable default argument for messages.

Using a mutable default argument can lead to unexpected behavior if the function is called multiple times, as all calls will share the same list instance.

-        messages: List = [],
+        messages: Optional[List] = None,

Add this check at the beginning of the method:

if messages is None:
    messages = []
🧰 Tools
🪛 Ruff (0.8.2)

13-13: Do not use mutable data structures for argument defaults

Replace with None; initialize within function

(B006)


52-86: Add error handling for the API call.

The method calls self.std_llm_client.completion() without any error handling. Consider adding a try-except block to handle potential API failures or exceptions gracefully.

-    response = self.std_llm_client.completion(
-        messages=messages,
-        model=model,
-        timeout=timeout,
-        temperature=temperature,
-        top_p=top_p,
-        n=n,
-        stream=stream,
-        stream_options=stream_options,
-        stop=stop,
-        stop_sequences=stop_sequences,
-        max_tokens=max_tokens,
-        presence_penalty=presence_penalty,
-        frequency_penalty=frequency_penalty,
-        logit_bias=logit_bias,
-        response_format=response_format,
-        seed=seed,
-        tools=tools,
-        tool_choice=tool_choice,
-        logprobs=logprobs,
-        top_logprobs=top_logprobs,
-        parallel_tool_calls=parallel_tool_calls,
-        deployment_id=deployment_id,
-        extra_headers=extra_headers,
-        functions=functions,
-        function_call=function_call,
-        base_url=base_url,
-        api_version=api_version,
-        api_key=api_key,
-        model_list=model_list,
-        drop_invalid_params=drop_invalid_params,
-        user=user,
-        **kwargs,
-    )
-    return response
+    try:
+        response = self.std_llm_client.completion(
+            messages=messages,
+            model=model,
+            timeout=timeout,
+            temperature=temperature,
+            top_p=top_p,
+            n=n,
+            stream=stream,
+            stream_options=stream_options,
+            stop=stop,
+            stop_sequences=stop_sequences,
+            max_tokens=max_tokens,
+            presence_penalty=presence_penalty,
+            frequency_penalty=frequency_penalty,
+            logit_bias=logit_bias,
+            response_format=response_format,
+            seed=seed,
+            tools=tools,
+            tool_choice=tool_choice,
+            logprobs=logprobs,
+            top_logprobs=top_logprobs,
+            parallel_tool_calls=parallel_tool_calls,
+            deployment_id=deployment_id,
+            extra_headers=extra_headers,
+            functions=functions,
+            function_call=function_call,
+            base_url=base_url,
+            api_version=api_version,
+            api_key=api_key,
+            model_list=model_list,
+            drop_invalid_params=drop_invalid_params,
+            user=user,
+            **kwargs,
+        )
+        return response
+    except Exception as e:
+        # Handle exceptions (consider logging or custom error response)
+        raise
edenai_apis/apis/together_ai/together_ai_api.py (1)

69-69: Fix mutable default argument for messages.

Using a mutable default argument can lead to unexpected behavior if the function is called multiple times, as all calls will share the same list instance.

-        messages: List = [],
+        messages: Optional[List] = None,

Add this check at the beginning of the method:

if messages is None:
    messages = []
🧰 Tools
🪛 Ruff (0.8.2)

69-69: Do not use mutable data structures for argument defaults

Replace with None; initialize within function

(B006)

edenai_apis/apis/google/google_llm_api.py (1)

13-13: Fix mutable default argument for messages.

Using a mutable default argument can lead to unexpected behavior if the function is called multiple times, as all calls will share the same list instance.

-        messages: List = [],
+        messages: Optional[List] = None,

Add this check at the beginning of the method:

if messages is None:
    messages = []
🧰 Tools
🪛 Ruff (0.8.2)

13-13: Do not use mutable data structures for argument defaults

Replace with None; initialize within function

(B006)

edenai_apis/apis/anthropic/anthropic_api.py (1)

142-142: Fix mutable default argument for messages.

Using a mutable default argument can lead to unexpected behavior if the function is called multiple times, as all calls will share the same list instance.

-        messages: List = [],
+        messages: Optional[List] = None,

Add this check at the beginning of the method:

if messages is None:
    messages = []
🧰 Tools
🪛 Ruff (0.8.2)

142-142: Do not use mutable data structures for argument defaults

Replace with None; initialize within function

(B006)

edenai_apis/apis/cohere/cohere_api.py (1)

54-54: Good initialization of the StdLLMEngine.

The standard LLM client is properly initialized with the API key, which is consistent with the pattern used for the existing LLMEngine initialization.

edenai_apis/apis/deepseek/deepseek_api.py (1)

31-31: Good initialization of the StdLLMEngine.

The standard LLM client is properly initialized with the API key, which is consistent with the pattern used for the existing LLMEngine initialization.

edenai_apis/apis/mistral/mistral_api.py (1)

40-40: Good initialization of the StdLLMEngine.

The standard LLM client is properly initialized with the API key, which is consistent with the pattern used for the existing LLMEngine initialization.

edenai_apis/apis/meta/meta_api.py (1)

50-56: Good AWS credential setup for StdLLMEngine.

The StdLLMEngine is properly initialized with the necessary AWS credentials, consistent with the pattern used for the existing LLMEngine.

edenai_apis/apis/replicate/replicate_api.py (3)

4-4: No issues with the expanded typing imports.
These additional typings improve clarity and correctness.


6-6: Import of httpx appears valid.
No performance or correctness issues identified with introducing httpx.


30-30: Inheritance looks correct.
Extending ReplicateApi with LlmInterface is consistent with the new LLM chat functionality.

edenai_apis/features/llm/chat/chat_dataclass.py (11)

1-4: Initial definitions and imports look good.
Dependence on pydantic for robust data validation is appropriate here.


6-12: ChatRole enum is clearly defined.
The roles SYSTEM, USER, ASSISTANT, FUNCTION, TOOL cover typical chat scenarios, enabling better type-safety.


14-29: ChatMessage structure is clear and extensible.
It accommodates function calls and tool calls, providing future-proofing for advanced features.


32-39: ChatCompletionModel enum for model variants is straightforward.
Allows typed references to GPT-based models.


41-60: Function / Tool definitions and ResponseFormat are well-structured.
They lend clarity for advanced usage scenarios, ensuring a standard schema.


126-135: Validator logic is effective.
Prohibits conflicts when both functions and tools are provided. This is a well-implemented safeguard.


137-148: ToolCallFunction and ToolCall classes are straightforward.
They appear consistent with other design elements for function invocation.


150-157: ChatCompletionChoice reason codes are well-defined.
The range of finish reasons covers typical completion outcomes.


159-183: UsageTokensDetails design is flexible and detailed.
This allows tracking of various token categories, ensuring usage insights.


186-195: ChatCompletionUsage aggregates usage tokens neatly.
The structuring is consistent and promotes clarity in usage reporting.


198-213: ChatDataClass successfully models the entire chat response.
Binds together completion details, usage, and unique identifiers.

Comment on lines +9 to +10
class OpenaiLLMApi(LlmInterface):

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Verification agent

🧩 Analysis chain

Implement __init__ method to initialize std_llm_client.

The llm__chat method uses self.std_llm_client but there's no initialization in this class. This could lead to runtime errors if std_llm_client is not set by a parent class or elsewhere.


🏁 Script executed:

#!/bin/bash
# Check if std_llm_client is initialized in parent classes or in the `OpenaiApi` class
# Look for initialization in parent or related classes
echo "Checking for std_llm_client initialization in LlmInterface:"
rg -n "std_llm_client\s*=" "edenai_apis/features/llm/llm_interface.py"

echo -e "\nChecking for std_llm_client initialization in the OpenaiApi class:"
rg -n "std_llm_client\s*=" "edenai_apis/apis/openai/openai_api.py"

echo -e "\nChecking for the usage pattern in other LLM API classes:"
rg -n "class \w+LLMApi.*LlmInterface" -A 15 "edenai_apis/" | grep -E "def __init__|std_llm_client"

Length of output: 732


Action Required: Implement the init Method in OpenaiLLMApi

The llm__chat method in this class references self.std_llm_client, yet this attribute isn’t initialized in the class. Unlike OpenaiApi (which initializes it in its __init__ method, see line 59 in edenai_apis/apis/openai/openai_api.py), OpenaiLLMApi extends LlmInterface which does not perform this initialization. This omission could lead to runtime errors when llm__chat is invoked.

  • File: edenai_apis/apis/openai/openai_llm_api.py (Lines 9-10)
  • Reference: Initialization exists in OpenaiApi (line 59 in edenai_apis/apis/openai/openai_api.py)

Please implement an __init__ method in OpenaiLLMApi that properly initializes self.std_llm_client (using the same or similar logic as in OpenaiApi) to ensure runtime stability.

Comment on lines +54 to +72
"""
Generate responses in a multimodal conversation using a chatbot.
Args:
messages (List[Dict[str, str]]): A list of messages exchanged in the conversation.
chatbot_global_action (Optional[str]): The global action or context for the chatbot.
temperature (float, optional): Controls the randomness of the response generation.
max_tokens (int, optional): The maximum number of tokens to generate for each response.
model (Optional[str], optional): The name or identifier of the model.
stop_sequences (Optional[List[str]], optional): A list of strings that, if encountered
in the generated response, will stop generation.
top_k (Optional[int], optional): Controls the diversity of the generated responses
by limiting the number of tokens considered at each step.
top_p (Optional[int], optional): Controls the diversity of the generated responses
by selecting from the most probable tokens whose cumulative probability exceeds
the given value.
stream (bool, optional): Whether to enable streaming for generating responses.
provider_params (dict, optional): Additional parameters specific to the provider
"""
raise NotImplementedError
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Update docstring to match method parameters.

The docstring doesn't accurately represent all the parameters defined in the method signature. It mentions parameters like chatbot_global_action and top_k that don't exist in the method, while omitting many parameters that do exist.

Consider updating the docstring to include accurate descriptions of all parameters, especially those that are crucial for the OpenAI compatibility that this PR aims to achieve, such as:

  • timeout
  • n
  • stream_options
  • stop
  • presence_penalty
  • frequency_penalty
  • logit_bias
  • response_format
  • seed
  • tools
  • tool_choice
  • logprobs
  • top_logprobs
  • parallel_tool_calls
  • deployment_id
  • extra_headers
  • functions
  • function_call
  • base_url
  • api_version
  • api_key
  • model_list
  • drop_invalid_params
  • user

Comment on lines +9 to +10
class AmazonLLMApi(LlmInterface):

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Verification agent

🧩 Analysis chain

Missing initialization of std_llm_client.

The class needs to initialize the std_llm_client attribute that's used in the llm__chat method, either by implementing a constructor or ensuring it's properly initialized in a parent class.


🏁 Script executed:

#!/bin/bash
# Check if there's an __init__ method that initializes std_llm_client
echo "Looking for std_llm_client initialization in this class or parent classes:"
rg -n "std_llm_client\s*=" "edenai_apis/apis/amazon/" --type py
echo -e "\nChecking if AmazonLLMApi is used as a parent class and how it's initialized:"
rg -n "class.*\(.*AmazonLLMApi.*\)" "edenai_apis/apis/amazon/" --type py

Length of output: 552


Action Required: Initialize std_llm_client in AmazonLLMApi

The AmazonLLMApi class in edenai_apis/apis/amazon/amazon_llm_api.py (lines 9-10) does not initialize the std_llm_client attribute, which is later used in the llm__chat method. Notably, a similar API implementation in amazon_api.py (line 46) correctly initializes this attribute using StdLLMEngine. To avoid runtime errors or unexpected behavior, please add an appropriate constructor (__init__) in AmazonLLMApi to ensure std_llm_client is properly set, or confirm that the needed initialization is inherited from the parent class.

Comment on lines +108 to +142
response = self.std_llm_client.completion(
messages=messages,
model=model,
timeout=timeout,
temperature=temperature,
top_p=top_p,
n=n,
stream=stream,
stream_options=stream_options,
stop=stop,
stop_sequences=stop_sequences,
max_tokens=max_tokens,
presence_penalty=presence_penalty,
frequency_penalty=frequency_penalty,
logit_bias=logit_bias,
response_format=response_format,
seed=seed,
tools=tools,
tool_choice=tool_choice,
logprobs=logprobs,
top_logprobs=top_logprobs,
parallel_tool_calls=parallel_tool_calls,
deployment_id=deployment_id,
extra_headers=extra_headers,
functions=functions,
function_call=function_call,
base_url=base_url,
api_version=api_version,
api_key=api_key,
model_list=model_list,
drop_invalid_params=drop_invalid_params,
user=user,
**kwargs,
)
return response
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Add error handling for the API call.

The method calls self.std_llm_client.completion() without any error handling. Consider adding a try-except block to handle potential API failures or exceptions gracefully.

-    response = self.std_llm_client.completion(
-        messages=messages,
-        model=model,
-        timeout=timeout,
-        temperature=temperature,
-        top_p=top_p,
-        n=n,
-        stream=stream,
-        stream_options=stream_options,
-        stop=stop,
-        stop_sequences=stop_sequences,
-        max_tokens=max_tokens,
-        presence_penalty=presence_penalty,
-        frequency_penalty=frequency_penalty,
-        logit_bias=logit_bias,
-        response_format=response_format,
-        seed=seed,
-        tools=tools,
-        tool_choice=tool_choice,
-        logprobs=logprobs,
-        top_logprobs=top_logprobs,
-        parallel_tool_calls=parallel_tool_calls,
-        deployment_id=deployment_id,
-        extra_headers=extra_headers,
-        functions=functions,
-        function_call=function_call,
-        base_url=base_url,
-        api_version=api_version,
-        api_key=api_key,
-        model_list=model_list,
-        drop_invalid_params=drop_invalid_params,
-        user=user,
-        **kwargs,
-    )
-    return response
+    try:
+        response = self.std_llm_client.completion(
+            messages=messages,
+            model=model,
+            timeout=timeout,
+            temperature=temperature,
+            top_p=top_p,
+            n=n,
+            stream=stream,
+            stream_options=stream_options,
+            stop=stop,
+            stop_sequences=stop_sequences,
+            max_tokens=max_tokens,
+            presence_penalty=presence_penalty,
+            frequency_penalty=frequency_penalty,
+            logit_bias=logit_bias,
+            response_format=response_format,
+            seed=seed,
+            tools=tools,
+            tool_choice=tool_choice,
+            logprobs=logprobs,
+            top_logprobs=top_logprobs,
+            parallel_tool_calls=parallel_tool_calls,
+            deployment_id=deployment_id,
+            extra_headers=extra_headers,
+            functions=functions,
+            function_call=function_call,
+            base_url=base_url,
+            api_version=api_version,
+            api_key=api_key,
+            model_list=model_list,
+            drop_invalid_params=drop_invalid_params,
+            user=user,
+            **kwargs,
+        )
+        return response
+    except Exception as e:
+        # Handle exceptions (consider logging or custom error response)
+        raise
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
response = self.std_llm_client.completion(
messages=messages,
model=model,
timeout=timeout,
temperature=temperature,
top_p=top_p,
n=n,
stream=stream,
stream_options=stream_options,
stop=stop,
stop_sequences=stop_sequences,
max_tokens=max_tokens,
presence_penalty=presence_penalty,
frequency_penalty=frequency_penalty,
logit_bias=logit_bias,
response_format=response_format,
seed=seed,
tools=tools,
tool_choice=tool_choice,
logprobs=logprobs,
top_logprobs=top_logprobs,
parallel_tool_calls=parallel_tool_calls,
deployment_id=deployment_id,
extra_headers=extra_headers,
functions=functions,
function_call=function_call,
base_url=base_url,
api_version=api_version,
api_key=api_key,
model_list=model_list,
drop_invalid_params=drop_invalid_params,
user=user,
**kwargs,
)
return response
try:
response = self.std_llm_client.completion(
messages=messages,
model=model,
timeout=timeout,
temperature=temperature,
top_p=top_p,
n=n,
stream=stream,
stream_options=stream_options,
stop=stop,
stop_sequences=stop_sequences,
max_tokens=max_tokens,
presence_penalty=presence_penalty,
frequency_penalty=frequency_penalty,
logit_bias=logit_bias,
response_format=response_format,
seed=seed,
tools=tools,
tool_choice=tool_choice,
logprobs=logprobs,
top_logprobs=top_logprobs,
parallel_tool_calls=parallel_tool_calls,
deployment_id=deployment_id,
extra_headers=extra_headers,
functions=functions,
function_call=function_call,
base_url=base_url,
api_version=api_version,
api_key=api_key,
model_list=model_list,
drop_invalid_params=drop_invalid_params,
user=user,
**kwargs,
)
return response
except Exception as e:
# Handle exceptions (consider logging or custom error response)
raise

Comment on lines +14 to +15
from edenai_apis.features.llm.llm_interface import LlmInterface
from edenai_apis.features.llm.chat.chat_dataclass import ChatDataClass
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Resolve duplicate import of ChatDataClass.

The ChatDataClass is imported twice, once from 'features.text.chat.chat_dataclass' (line 20) and again from 'features.llm.chat.chat_dataclass' (line 15), causing a redefinition.

-from edenai_apis.features.llm.chat.chat_dataclass import ChatDataClass
+from edenai_apis.features.llm.chat.chat_dataclass import ChatDataClass as LlmChatDataClass

Then update the return type in the method signature:

-    ) -> ChatDataClass:
+    ) -> LlmChatDataClass:
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
from edenai_apis.features.llm.llm_interface import LlmInterface
from edenai_apis.features.llm.chat.chat_dataclass import ChatDataClass
from edenai_apis.features.llm.llm_interface import LlmInterface
from edenai_apis.features.llm.chat.chat_dataclass import ChatDataClass as LlmChatDataClass
# ... other imports and code ...
# Example method update based on the diff snippet:
def some_method(self, some_param) -> LlmChatDataClass:
# method implementation
pass
🧰 Tools
🪛 Ruff (0.8.2)

15-15: Redefinition of unused ChatDataClass from line 7

(F811)

@@ -20,15 +22,17 @@
SpellCheckDataClass,
)
from edenai_apis.features.text.summarize import SummarizeDataClass
from edenai_apis.llmengine.llm_engine import LLMEngine
from edenai_apis.llmengine.llm_engine import LLMEngine, StdLLMEngine
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Double import of ChatDataClass detected.

The same class name is imported from two different modules which could lead to confusion and potential bugs:

  1. Line 9: from edenai_apis.features.text import ChatDataClass
  2. Line 32: from edenai_apis.features.llm.chat.chat_dataclass import ChatDataClass

This creates ambiguity about which implementation is being used and may cause unexpected behavior.

Resolve this by using an alias for one of the imports:

- from edenai_apis.features.llm.chat.chat_dataclass import ChatDataClass
+ from edenai_apis.features.llm.chat.chat_dataclass import ChatDataClass as LlmChatDataClass

Then use the appropriate class name for the return type:

- def llm__chat(...) -> ChatDataClass:
+ def llm__chat(...) -> LlmChatDataClass:
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
from edenai_apis.llmengine.llm_engine import LLMEngine, StdLLMEngine
from edenai_apis.features.text import ChatDataClass
from edenai_apis.llmengine.llm_engine import LLMEngine, StdLLMEngine
- from edenai_apis.features.llm.chat.chat_dataclass import ChatDataClass
+ from edenai_apis.features.llm.chat.chat_dataclass import ChatDataClass as LlmChatDataClass
# ... (other parts of the file)
- def llm__chat(self, ... ) -> ChatDataClass:
+ def llm__chat(self, ... ) -> LlmChatDataClass:
# function implementation remains unchanged
...

@@ -8,9 +11,12 @@
from edenai_apis.loaders.loaders import load_provider
from edenai_apis.loaders.data_loader import ProviderDataEnum
from edenai_apis.llmengine import LLMEngine
from edenai_apis.features.llm.llm_interface import LlmInterface
from edenai_apis.llmengine.llm_engine import StdLLMEngine
from edenai_apis.features.llm.chat.chat_dataclass import ChatDataClass
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Double import of ChatDataClass detected.

The same class name is imported from two different modules which could lead to confusion:

  1. Line 6: from edenai_apis.features.text import ChatDataClass
  2. Line 16: from edenai_apis.features.llm.chat.chat_dataclass import ChatDataClass

This creates ambiguity about which implementation is being used.

Resolve this by using an alias for one of the imports:

- from edenai_apis.features.llm.chat.chat_dataclass import ChatDataClass
+ from edenai_apis.features.llm.chat.chat_dataclass import ChatDataClass as LlmChatDataClass

Then use the appropriate class name for the return type:

- def llm__chat(...) -> ChatDataClass:
+ def llm__chat(...) -> LlmChatDataClass:
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
from edenai_apis.features.llm.chat.chat_dataclass import ChatDataClass
# Existing import from line 6 remains unchanged:
from edenai_apis.features.text import ChatDataClass
# Updated import on line 16 with alias to resolve ambiguity:
from edenai_apis.features.llm.chat.chat_dataclass import ChatDataClass as LlmChatDataClass
# ... other code ...
# Updated function signature to use the aliased class in its return type:
def llm__chat(...)-> LlmChatDataClass:
# function implementation here
pass
🧰 Tools
🪛 Ruff (0.8.2)

16-16: Redefinition of unused ChatDataClass from line 6

(F811)

from edenai_apis.llmengine.llm_engine import LLMEngine
from edenai_apis.llmengine.llm_engine import LLMEngine, StdLLMEngine
from edenai_apis.features.llm.llm_interface import LlmInterface
from edenai_apis.features.llm.chat.chat_dataclass import ChatDataClass
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Double import of ChatDataClass detected.

The same class name is imported from two different modules which could lead to confusion:

  1. Line 7: from edenai_apis.features.text.chat.chat_dataclass import ChatDataClass
  2. Line 23: from edenai_apis.features.llm.chat.chat_dataclass import ChatDataClass

This creates ambiguity about which implementation is being used.

Resolve this by using an alias for one of the imports:

- from edenai_apis.features.llm.chat.chat_dataclass import ChatDataClass
+ from edenai_apis.features.llm.chat.chat_dataclass import ChatDataClass as LlmChatDataClass

Then use the appropriate class name for the return type:

- def llm__chat(...) -> ChatDataClass:
+ def llm__chat(...) -> LlmChatDataClass:
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
from edenai_apis.features.llm.chat.chat_dataclass import ChatDataClass
from edenai_apis.features.text.chat.chat_dataclass import ChatDataClass
from edenai_apis.features.llm.chat.chat_dataclass import ChatDataClass as LlmChatDataClass
# ... other parts of the file ...
def llm__chat(...params...) -> LlmChatDataClass:
# function implementation remains unchanged
pass
🧰 Tools
🪛 Ruff (0.8.2)

23-23: Redefinition of unused ChatDataClass from line 7

(F811)

import json
import boto3

from edenai_apis.features.llm.llm_interface import LlmInterface
from edenai_apis.features.llm.chat.chat_dataclass import ChatDataClass
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Double import of ChatDataClass detected.

The same class name is imported from two different modules which could lead to confusion:

  1. Line 9: from edenai_apis.features.text.chat.chat_dataclass import ChatDataClass
  2. Line 25: from edenai_apis.features.llm.chat.chat_dataclass import ChatDataClass

This creates ambiguity about which implementation is being used.

Resolve this by using an alias for one of the imports:

- from edenai_apis.features.llm.chat.chat_dataclass import ChatDataClass
+ from edenai_apis.features.llm.chat.chat_dataclass import ChatDataClass as LlmChatDataClass

Then use the appropriate class name for the return type:

- def llm__chat(...) -> ChatDataClass:
+ def llm__chat(...) -> LlmChatDataClass:
🧰 Tools
🪛 Ruff (0.8.2)

25-25: Redefinition of unused ChatDataClass from line 9

(F811)

Comment on lines +245 to +247
def llm__chat(
self,
messages: List = [],
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Avoid mutable default argument for messages.
Using List = [] for a function argument can lead to unexpected shared state.

-def llm__chat(
-    self,
-    messages: List = [],
+def llm__chat(
+    self,
+    messages: Optional[List] = None,
):
    if messages is None:
        messages = []
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
def llm__chat(
self,
messages: List = [],
def llm__chat(
self,
messages: Optional[List] = None,
):
if messages is None:
messages = []
# ...rest of the function implementation...
🧰 Tools
🪛 Ruff (0.8.2)

247-247: Do not use mutable data structures for argument defaults

Replace with None; initialize within function

(B006)

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🔭 Outside diff range comments (1)
edenai_apis/tests/llmengine/test_tools.py (1)

31-75: ⚠️ Potential issue

Duplicate test method names.

There are two test methods with the identical name test_tool_type_instantiation. This can cause confusion and potentially lead to only one of these tests being executed depending on the test runner.

Rename one of the test methods to better reflect its purpose:

- def test_tool_type_instantiation(self):
+ def test_tool_type_function_modification(self):

This change will ensure both tests are properly discoverable and executed.

Also applies to: 76-143

🧹 Nitpick comments (1)
edenai_apis/tests/llmengine/test_tools.py (1)

183-183: API key hardcoded in test file.

While this is acceptable for testing purposes, consider using a test constant or environment variable for consistency across tests.

-            "api_key": "opeizaopei",
+            "api_key": TEST_API_KEY,  # Define this as a constant at the top of the test file
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between b759c0f and 393bc18.

📒 Files selected for processing (8)
  • .docsrc/conf.py (1 hunks)
  • edenai_apis/interface.py (1 hunks)
  • edenai_apis/llmengine/llm_engine.py (1 hunks)
  • edenai_apis/tests/features/test_async_features.py (1 hunks)
  • edenai_apis/tests/features/test_sync_features.py (1 hunks)
  • edenai_apis/tests/llmengine/test_model_management_interface.py (1 hunks)
  • edenai_apis/tests/llmengine/test_tools.py (2 hunks)
  • setup.py (1 hunks)
✅ Files skipped from review due to trivial changes (3)
  • setup.py
  • .docsrc/conf.py
  • edenai_apis/tests/llmengine/test_model_management_interface.py
🚧 Files skipped from review as they are similar to previous changes (4)
  • edenai_apis/interface.py
  • edenai_apis/tests/features/test_async_features.py
  • edenai_apis/tests/features/test_sync_features.py
  • edenai_apis/llmengine/llm_engine.py
⏰ Context from checks skipped due to timeout of 90000ms (1)
  • GitHub Check: test
🔇 Additional comments (2)
edenai_apis/tests/llmengine/test_tools.py (2)

165-171: Improved structure matches OpenAI's API format.

The restructuring of the tool_calls variable is a positive change that better aligns with OpenAI's API format. This is consistent with the PR objective of making Eden AI chat API OpenAI-compatible.


186-191: Improved assertion readability.

The multi-line format makes the assertion more readable while maintaining the same functionality.

@juandavidcruzgomez juandavidcruzgomez requested review from Daggx and removed request for Daggx March 3, 2025 22:39
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🧹 Nitpick comments (9)
edenai_apis/tests/loaders/test_data_loader.py (5)

132-136: Enhance the error message to match the conditional logic.

The code correctly handles the different structures for LLM vs. other features, but the error message on line 138 only references "Original_response and standradized_response" even when the LLM check for "choices" key fails.

        try:
            if feature == "llm":
                output["choices"]
            else:
                output["original_response"]
                output["standardized_response"]
        except KeyError:
-            pytest.fail("Original_response and standradized_response not found")
+            if feature == "llm":
+                pytest.fail("'choices' key not found in LLM output")
+            else:
+                pytest.fail("'original_response' and 'standardized_response' keys not found")

138-138: Fix typo in error message.

There's a spelling error in the error message: "standradized_response" should be "standardized_response".

        except KeyError:
-            pytest.fail("Original_response and standradized_response not found")
+            pytest.fail("Original_response and standardized_response not found")

132-136: Consider a more maintainable approach for feature-specific output validation.

The current conditional approach works but could become unwieldy if more features with different output structures are added. Consider a more scalable approach such as a mapping of feature to expected keys.

+        # Define the expected keys for each feature type
+        feature_output_keys = {
+            "llm": ["choices"],
+            # Default keys for other features
+            "default": ["original_response", "standardized_response"]
+        }
+
         try:
-            if feature == "llm":
-                output["choices"]
-            else:
-                output["original_response"]
-                output["standardized_response"]
+            # Get expected keys for this feature or use default
+            expected_keys = feature_output_keys.get(feature, feature_output_keys["default"])
+            for key in expected_keys:
+                output[key]  # This will raise KeyError if key doesn't exist
         except KeyError:
-            pytest.fail("Original_response and standradized_response not found")
+            expected_keys_str = ", ".join([f"'{key}'" for key in expected_keys])
+            pytest.fail(f"Expected keys {expected_keys_str} not found in output")

123-123: Fix typo in test method name.

The method name has a spelling error: "paramters" should be "parameters".

-    def test_load_output_valid_paramters(self, provider, feature, subfeature, phase):
+    def test_load_output_valid_parameters(self, provider, feature, subfeature, phase):

132-136: Add a docstring to explain the LLM output structure.

Since the LLM feature has a different output structure than other features, adding a comment would help clarify why this special handling exists.

        try:
+            # LLM feature uses 'choices' key instead of 'original_response' and 'standardized_response'
+            # to align with OpenAI-compatible structure
            if feature == "llm":
                output["choices"]
            else:
                output["original_response"]
                output["standardized_response"]
edenai_apis/tests/features/test_interfaces.py (1)

39-42: Document the reason for excluding text__chat from signature verification

The code now excludes the text__chat method from signature verification, likely to accommodate differences required for OpenAI compatibility as mentioned in the PR objectives. Adding a comment explaining this exclusion would improve code maintainability.

-    if implemented_method and method_name != "text__chat":
+    # text__chat is excluded from signature verification because it needs to maintain
+    # compatibility with OpenAI's interface which may differ from other providers
+    if implemented_method and method_name != "text__chat":
edenai_apis/llmengine/utils/moderation.py (3)

49-66: Add error handling for concurrent moderation tasks.

The function executes multiple moderation tasks concurrently but doesn't handle potential exceptions properly. If one task fails, it could cause the entire operation to fail without clear error information.

async def standard_moderation(args, **kwargs):
    api_settings = load_provider(ProviderDataEnum.KEY, "openai", api_keys={})

    api_key = api_settings.get("api_key")
    headers = {"Authorization": f"Bearer {api_key}"}

    tasks = []

    messages = kwargs.get("messages", [])

    for message in messages:
        if "content" in message:
            tasks.append(moderate_content(headers, message["content"]))

-    async with aiohttp.ClientSession() as session:
-        await asyncio.gather(*tasks)
+    try:
+        # Execute all moderation tasks concurrently
+        await asyncio.gather(*tasks)
+    except ProviderException as e:
+        # Re-raise provider exceptions
+        raise e
+    except Exception as e:
+        # Wrap other exceptions
+        raise ProviderException(f"Moderation failed: {str(e)}", code=500)
🧰 Tools
🪛 Ruff (0.8.2)

63-63: Local variable session is assigned to but never used

Remove assignment to unused variable session

(F841)


169-176: Consider optimizing session management across the moderation process.

The moderate_std decorator is similar to the existing moderate function but uses a different moderation function. This approach works, but there's an opportunity to improve efficiency by sharing an aiohttp session between moderation requests.

Consider refactoring to allow passing a shared session to the moderation functions. This would be especially valuable if your application makes many moderation requests in succession.

For example, you could:

  1. Create a session pool or context manager
  2. Pass the session to both decorators and moderation functions
  3. Reuse sessions where possible

This would reduce connection overhead and improve performance, especially for high-volume API usage.


169-176: Document the differences between the two moderation decorators.

You now have two decorators (moderate and moderate_std) with similar purposes but different implementations. It's not immediately clear when one should be used over the other.

Add docstrings to clarify the purpose and usage context of each decorator:

def moderate_std(func):
+    """
+    Decorator that applies standard moderation for chat messages.
+    
+    This decorator is specifically designed for the OpenAI-compatible chat API
+    and only processes message content using the standard_moderation function.
+    
+    Args:
+        func: The function to decorate
+        
+    Returns:
+        Decorated function that performs content moderation before execution
+    """
    @wraps(func)
    def wrapper(self, *args, **kwargs):
        if kwargs.get("moderate_content"):
            async_to_sync(standard_moderation)(*args, **kwargs)
        return func(self, *args, **kwargs)

    return wrapper
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 393bc18 and 2e7dd4e.

📒 Files selected for processing (5)
  • edenai_apis/llmengine/llm_engine.py (4 hunks)
  • edenai_apis/llmengine/utils/moderation.py (2 hunks)
  • edenai_apis/tests/features/test_interfaces.py (2 hunks)
  • edenai_apis/tests/llmengine/conftest.py (1 hunks)
  • edenai_apis/tests/loaders/test_data_loader.py (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • edenai_apis/llmengine/llm_engine.py
🧰 Additional context used
🪛 Ruff (0.8.2)
edenai_apis/tests/features/test_interfaces.py

11-11: difflib imported but unused

Remove unused import: difflib

(F401)

edenai_apis/llmengine/utils/moderation.py

63-63: Local variable session is assigned to but never used

Remove assignment to unused variable session

(F841)

⏰ Context from checks skipped due to timeout of 90000ms (1)
  • GitHub Check: test
🔇 Additional comments (3)
edenai_apis/tests/llmengine/conftest.py (2)

173-199: The mapping_providers fixture is well-structured

The fixture returns a comprehensive list of provider mappings as tuples, appropriately handling edge cases like empty strings and None values.


192-192:

✅ Verification successful

Provider mapping updated from "amazon" to "bedrock"

This change aligns the Amazon provider with the Amazon Bedrock service, which is Amazon's managed service for foundation models. This is consistent with the PR's goal of making the Eden AI chat API more compatible with OpenAI standards and implementing Amazon chat features.


🏁 Script executed:

#!/bin/bash
# Description: Check if there are any references to the previous provider mapping that might need to be updated

# Look for direct references to the previous amazon mapping in tests
echo "Checking for direct 'amazon' provider references in tests that might need updating:"
rg -g "*.py" "amazon.*provider" ./edenai_apis/tests/ | grep -v "bedrock"

# Look for imports of Amazon API classes to understand the new implementation
echo -e "\nChecking Amazon API class imports to understand structure:"
rg -g "*.py" "import.*Amazon" ./edenai_apis/

Length of output: 1444


Mapping Update Verified: 'amazon' now mapped to 'bedrock'

The test file edenai_apis/tests/llmengine/conftest.py now correctly reflects the new mapping using ("amazon", "bedrock"), which aligns the provider configuration with Amazon’s Bedrock service. Verification shows that:

  • No stray references to the old mapping exist in the tests.
  • The Amazon API imports in edenai_apis/apis/amazon/ remain as expected.
edenai_apis/tests/features/test_interfaces.py (1)

38-42:

❓ Verification inconclusive

Consider adding a test for the excluded text__chat method

You've excluded the text__chat method from signature verification, which makes sense if it needs flexibility across different provider implementations to achieve OpenAI compatibility. However, this means there's no validation for this method's signature, which could lead to inconsistencies.

Consider adding a separate test case specifically for the text__chat method that verifies its compatibility with the OpenAI interface or documents why the signature can vary across implementations.


🏁 Script executed:

#!/bin/bash
# Description: Check if there's any existing validation for text__chat signatures
# or documentation explaining the exclusion

# Check for any text__chat tests
echo "Searching for text__chat tests or validations..."
rg "text__chat.*test|test.*text__chat" --type py

# Look for comments explaining the exclusion
echo -e "\nSearching for explanatory comments..."
rg "text__chat.*skip|exclude.*text__chat|ignore.*text__chat" --type py -A 3 -B 3

Length of output: 331


Action Required: Add Dedicated Testing or Documentation for text__chat

It appears that no tests or explanatory comments were found regarding the text__chat signature. While intentionally excluding it from interface validation might be necessary for flexibility, the absence of validation could introduce inconsistencies. Please consider one of the following:

  • Add a dedicated test case: Verify that the text__chat implementation is compatible with the OpenAI interface requirements.
  • Provide explicit documentation: Clearly explain why the signature for text__chat can differ across providers and outline any constraints.

@@ -8,6 +8,8 @@

from edenai_apis.loaders.data_loader import load_class

import difflib
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Remove unused import

The difflib module is imported but never used in this file.

-import difflib
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
import difflib
🧰 Tools
🪛 Ruff (0.8.2)

11-11: difflib imported but unused

Remove unused import: difflib

(F401)

Comment on lines 49 to 66
async def standard_moderation(args, **kwargs):
api_settings = load_provider(ProviderDataEnum.KEY, "openai", api_keys={})

api_key = api_settings.get("api_key")
headers = {"Authorization": f"Bearer {api_key}"}

tasks = []

messages = kwargs.get("messages", [])

for message in messages:
if "content" in message:
tasks.append(moderate_content(headers, message["content"]))

async with aiohttp.ClientSession() as session:
await asyncio.gather(*tasks)


Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Fix the unused ClientSession and consider refactoring for efficiency.

The standard_moderation function has two main issues:

  1. You create a ClientSession on line 63 but never use it, as the actual HTTP requests are made inside the moderate_content function with its own sessions.
  2. Creating multiple aiohttp sessions (one for each message) is inefficient compared to reusing a single session.
async def standard_moderation(args, **kwargs):
    api_settings = load_provider(ProviderDataEnum.KEY, "openai", api_keys={})

    api_key = api_settings.get("api_key")
    headers = {"Authorization": f"Bearer {api_key}"}

    tasks = []

    messages = kwargs.get("messages", [])

    for message in messages:
        if "content" in message:
            tasks.append(moderate_content(headers, message["content"]))

-    async with aiohttp.ClientSession() as session:
-        await asyncio.gather(*tasks)
+    # Execute all moderation tasks concurrently
+    await asyncio.gather(*tasks)

-    
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
async def standard_moderation(args, **kwargs):
api_settings = load_provider(ProviderDataEnum.KEY, "openai", api_keys={})
api_key = api_settings.get("api_key")
headers = {"Authorization": f"Bearer {api_key}"}
tasks = []
messages = kwargs.get("messages", [])
for message in messages:
if "content" in message:
tasks.append(moderate_content(headers, message["content"]))
async with aiohttp.ClientSession() as session:
await asyncio.gather(*tasks)
async def standard_moderation(args, **kwargs):
api_settings = load_provider(ProviderDataEnum.KEY, "openai", api_keys={})
api_key = api_settings.get("api_key")
headers = {"Authorization": f"Bearer {api_key}"}
tasks = []
messages = kwargs.get("messages", [])
for message in messages:
if "content" in message:
tasks.append(moderate_content(headers, message["content"]))
# Execute all moderation tasks concurrently
await asyncio.gather(*tasks)
🧰 Tools
🪛 Ruff (0.8.2)

63-63: Local variable session is assigned to but never used

Remove assignment to unused variable session

(F841)

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

♻️ Duplicate comments (1)
edenai_apis/llmengine/utils/moderation.py (1)

49-66: ⚠️ Potential issue

Fix the unused ClientSession issue.

The standard_moderation function creates a ClientSession in line 63 but never uses it since the actual HTTP requests happen inside the moderate_content function where separate sessions are created. This matches the issue that was already identified in a previous review.

async def standard_moderation(*args, **kwargs):
    api_settings = load_provider(ProviderDataEnum.KEY, "openai", api_keys={})

    api_key = api_settings.get("api_key")
    headers = {"Authorization": f"Bearer {api_key}"}

    tasks = []

    messages = kwargs.get("messages", [])

    for message in messages:
        if "content" in message:
            tasks.append(moderate_content(headers, message["content"]))

-    async with aiohttp.ClientSession() as session:
-        await asyncio.gather(*tasks)
-
-    
+    # Execute all moderation tasks concurrently
+    await asyncio.gather(*tasks)
🧰 Tools
🪛 Ruff (0.8.2)

63-63: Local variable session is assigned to but never used

Remove assignment to unused variable session

(F841)

🧹 Nitpick comments (3)
edenai_apis/llmengine/utils/moderation.py (3)

58-61: Consider adding validation for message format.

The code assumes messages follow a specific structure with a "content" key. It might be beneficial to add validation for the message format or handle cases where a message might have a different structure.

    messages = kwargs.get("messages", [])

    for message in messages:
+        # Ensure message is a dictionary and has the expected structure
+        if not isinstance(message, dict):
+            continue
        if "content" in message:
            tasks.append(moderate_content(headers, message["content"]))

49-66: Consider handling empty task list.

The current implementation creates an empty task list if no messages contain content, but still calls asyncio.gather(). While this works, it's a good practice to handle the empty case explicitly.

    for message in messages:
        if "content" in message:
            tasks.append(moderate_content(headers, message["content"]))

-    async with aiohttp.ClientSession() as session:
-        await asyncio.gather(*tasks)
+    # Only gather if there are tasks to process
+    if tasks:
+        await asyncio.gather(*tasks)
🧰 Tools
🪛 Ruff (0.8.2)

63-63: Local variable session is assigned to but never used

Remove assignment to unused variable session

(F841)


169-176: Consider adding proper error handling in the decorator.

The decorator should handle potential exceptions from the standard_moderation function to ensure the main function still executes even if moderation fails (unless that's a critical requirement).

def moderate_std(func):
    @wraps(func)
    def wrapper(self, *args, **kwargs):
        if kwargs.get("moderate_content"):
-            async_to_sync(standard_moderation)(*args, **kwargs)
+            try:
+                async_to_sync(standard_moderation)(*args, **kwargs)
+            except Exception as e:
+                # Log the exception but allow the function to continue
+                # Replace with proper logging as needed
+                print(f"Content moderation failed: {str(e)}")
        return func(self, *args, **kwargs)

    return wrapper
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 2e7dd4e and 4634680.

📒 Files selected for processing (1)
  • edenai_apis/llmengine/utils/moderation.py (2 hunks)
🧰 Additional context used
🪛 Ruff (0.8.2)
edenai_apis/llmengine/utils/moderation.py

63-63: Local variable session is assigned to but never used

Remove assignment to unused variable session

(F841)

⏰ Context from checks skipped due to timeout of 90000ms (1)
  • GitHub Check: test
🔇 Additional comments (1)
edenai_apis/llmengine/utils/moderation.py (1)

169-176: LGTM! Appropriate decorator implementation.

Good implementation of the moderate_std decorator that follows the same pattern as the existing moderate decorator, but uses the new standard_moderation function.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Nitpick comments (1)
edenai_apis/apis/cohere/outputs/llm/chat_output.json (1)

19-20: Timing Information:
The included timing fields "provider_time" (with a large integer value) and "edenai_time" (currently null) are useful for performance metrics. Make sure that downstream consumers handle a null value gracefully. Additionally, consider documenting the time unit (e.g., milliseconds or seconds) for clarity.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 4634680 and 7f66caa.

📒 Files selected for processing (3)
  • edenai_apis/apis/cohere/outputs/llm/chat_output.json (1 hunks)
  • edenai_apis/features/llm/chat/chat_response.json (1 hunks)
  • edenai_apis/tests/features/test_sync_features.py (2 hunks)
🚧 Files skipped from review as they are similar to previous changes (2)
  • edenai_apis/features/llm/chat/chat_response.json
  • edenai_apis/tests/features/test_sync_features.py
⏰ Context from checks skipped due to timeout of 90000ms (1)
  • GitHub Check: test
🔇 Additional comments (4)
edenai_apis/apis/cohere/outputs/llm/chat_output.json (4)

1-6: Metadata and General Structure:
The top-level fields (such as "id", "created", "model", "object", and "system_fingerprint") are defined clearly and follow a consistent structure. Consider adding documentation (or a JSON schema) elsewhere in the repository to detail the expected formats and units (e.g., the unit for "created" could be specified as a Unix timestamp).


7-18: Chat Choices Array:
The "choices" array is well-structured with a single object providing the chat completion details. The nested "message" object correctly includes keys like "content", "role", "tool_calls", and "function_call". If the API might eventually support multiple choices, ensure that client code is prepared to iterate over this array.


21-38: Usage Metrics Detail:
The "usage" object provides a comprehensive breakdown of token counts, including overall tokens and detailed sub-categories for both completion and prompt tokens. Note that some fields, such as "text_tokens", are set to null; ensure that any client consuming these metrics can handle missing values appropriately. If these fields are optional, this should be clearly documented.


39-40: Service Tier and Cost Evaluation:
The final fields "service_tier" and "cost" are straightforward and appear to align with the API’s pricing model and service categorization. Verify that these values are consistent with the broader business logic and that any cost calculations elsewhere in the system reference the same definitions.

@juandavidcruzgomez juandavidcruzgomez merged commit 991fac8 into master Mar 4, 2025
4 checks passed
@Daggx Daggx deleted the SD2-1118-make-eden-ai-chat-api-open-ai-compatible branch March 6, 2025 12:58
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants