Skip to content
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

enhance workflow code for Python #412

Merged
merged 27 commits into from
Nov 6, 2024
Merged

enhance workflow code for Python #412

merged 27 commits into from
Nov 6, 2024

Conversation

leehuwuj
Copy link
Collaborator

@leehuwuj leehuwuj commented Nov 4, 2024

  • Update FunctionCallingAgent. Group multiple tool calls into a progress and show the progress to the UI.
  • Update form filling use case to use FunctionCallingAgent.

Summary by CodeRabbit

  • New Features

    • Introduced a new create_workflow function for financial report generation and form filling workflows.
    • Added a form_filling agent to the multiagent template, enhancing its capabilities.
    • Implemented a structured workflow for filling missing cells in CSV files.
    • Expanded the multiagent template tests by including a new agent, "form_filling".
    • Added event handling classes to manage agent interactions and improve response structures.
  • Bug Fixes

    • Improved error handling in workflow processes, ensuring better logging and response management.
  • Documentation

    • Updated README files to reflect changes in file paths and project structure for better clarity.
  • Chores

    • Removed outdated files related to previous implementations of financial report and form filling functionalities.

Copy link

changeset-bot bot commented Nov 4, 2024

🦋 Changeset detected

Latest commit: 6e5486c

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 1 package
Name Type
create-llama Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

Copy link

coderabbitai bot commented Nov 4, 2024

Walkthrough

This pull request introduces significant changes, including the creation of new workflows for generating financial reports and filling forms, along with optimizations to existing workflow code for Python. It updates various documentation paths and modifies multi-agent template tests by adding a new agent. Several files related to financial reporting and form filling have been deleted, consolidating their functionalities into new workflow structures. The overall architecture has been restructured to enhance clarity and efficiency in managing agent interactions and workflows.

Changes

File Path Change Summary
.changeset/light-parrots-work.md Introduced a patch "create-llama" for optimizing workflow code generation for Python.
e2e/shared/multiagent_template.spec.ts Added "form_filling" to templateAgents; added conditional skip to specific tests.
templates/components/agents/python/blog/README-template.md Updated file paths for agent interaction methods from ./app/examples/ to ./app/agents/.
templates/components/agents/python/blog/app/workflows/init.py Added create_workflow to __all__ for export.
templates/components/agents/python/blog/app/workflows/blog.py Renamed get_chat_engine to create_workflow and updated its signature.
templates/components/agents/python/blog/app/workflows/single.py Modified AgentRunEvent response structure and added streaming input handling methods.
templates/components/agents/python/financial_report/README-template.md Updated workflow module path from app/financial_report/workflow.py to app/workflows/.
templates/components/agents/python/financial_report/app/agents/analyst.py Deleted file containing analyst agent functionality.
templates/components/agents/python/financial_report/app/agents/reporter.py Deleted file containing reporter agent functionality.
templates/components/agents/python/financial_report/app/agents/researcher.py Deleted file containing researcher agent functionality.
templates/components/agents/python/financial_report/app/agents/workflow.py Deleted file containing financial report generation workflow.
templates/components/agents/python/financial_report/app/engine/engine.py Deleted file containing get_chat_engine function.
templates/components/agents/python/financial_report/app/workflows/init.py Added create_workflow to __all__ for export.
templates/components/agents/python/financial_report/app/workflows/financial_report.py Introduced new file for financial report generation workflow with event handling.
templates/components/agents/python/form_filling/README-template.md Updated API editing path from app/agents/form_filling.py to app/workflows/form_filling.py.
templates/components/agents/python/form_filling/app/agents/form_filling.py Deleted file containing form filling workflow functionality.
templates/components/agents/python/form_filling/app/engine/engine.py Deleted file containing get_chat_engine function.
templates/components/agents/python/form_filling/app/workflows/init.py Added create_workflow to __all__ for export.
templates/components/agents/python/form_filling/app/workflows/form_filling.py Introduced new file for form filling workflow with event handling.
templates/components/multiagent/python/app/api/routers/chat.py Modified chat endpoint to utilize create_workflow and updated event handling.
templates/components/multiagent/python/app/workflows/events.py Introduced AgentRunEventType and AgentRunEvent classes for event handling.
templates/components/multiagent/python/app/workflows/function_calling_agent.py Introduced FunctionCallingAgent class for LLM interactions with tools.
templates/components/multiagent/python/app/workflows/tools.py Introduced classes and functions for managing tool interactions in chat workflows.

Possibly related PRs

Suggested reviewers

  • marcusschiesser

Poem

In the burrow where changes bloom,
Workflows dance and find their room.
Forms are filled, reports take flight,
Optimized paths shine ever bright.
With every hop, new features grow,
A rabbit's joy in code's sweet flow! 🐇✨


Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media?

❤️ Share
🪧 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 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.

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.

@leehuwuj leehuwuj force-pushed the lee/enhance-workflow branch from 2832d0b to 872ec84 Compare November 5, 2024 08:55
@marcusschiesser marcusschiesser changed the title enhance workflow code enhance workflow code for Python Nov 5, 2024
@leehuwuj leehuwuj force-pushed the lee/enhance-workflow branch from d4416eb to ee0c607 Compare November 6, 2024 02:13
@leehuwuj leehuwuj marked this pull request as ready for review November 6, 2024 02:41
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: 10

🧹 Outside diff range and nitpick comments (18)
templates/components/multiagent/python/app/workflows/events.py (2)

7-9: Add docstring to document the enum's purpose.

While the enum is well-structured, adding a docstring would help other developers understand its purpose and usage in the context of agent run events.

 class AgentRunEventType(Enum):
+    """Enum defining types of events that can occur during agent execution.
+    
+    TEXT: Regular text output from the agent
+    PROGRESS: Progress indicator for ongoing operations
+    """
     TEXT = "text"
     PROGRESS = "progress"

12-27: Enhance type safety and documentation while maintaining good structure.

The class implementation is solid and aligns well with the PR objectives. Consider these improvements:

+from typing import Dict, Any
+
 class AgentRunEvent(Event):
+    """Event class for tracking and reporting agent execution status.
+
+    Attributes:
+        name: The name of the agent
+        msg: The message content
+        event_type: Type of event (text or progress)
+        data: Optional additional data associated with the event
+    """
     name: str
     msg: str
     event_type: AgentRunEventType = AgentRunEventType.TEXT
-    data: Optional[dict] = None
+    data: Optional[Dict[str, Any]] = None

     def to_response(self) -> dict:
+        """Convert the event to a structured response dictionary.
+
+        Returns:
+            Dict containing the formatted event data.
+        """
         return {
templates/components/multiagent/python/app/api/routers/chat.py (2)

26-27: Ensure proper handling when doc_ids is empty

If data.get_chat_document_ids() returns an empty list or None, generate_filters(doc_ids) may not function as intended. Consider adding checks to handle these cases to prevent potential errors downstream.


34-34: Consider renaming the input parameter to avoid shadowing built-in function

Using input as a parameter name can shadow Python's built-in input() function. To prevent any potential confusion or unintended side effects, consider renaming the parameter to something like user_input.

templates/components/multiagent/python/app/workflows/function_calling_agent.py (3)

37-40: Ensure consistent type annotations for optional parameters

In the __init__ method, optional parameters use both Type | None and Optional[Type] syntax inconsistently. For better code readability and compatibility with earlier Python versions, consider using Optional[Type] consistently.

Apply this diff to standardize the type annotations:

-            llm: FunctionCallingLLM | None = None,
-            tools: List[BaseTool] | None = None,
-            system_prompt: str | None = None,
+            llm: Optional[FunctionCallingLLM] = None,
+            tools: Optional[List[BaseTool]] = None,
+            system_prompt: Optional[str] = None,

47-47: Address the type ignore comment on super().__init__

The # type: ignore comment on the super().__init__ call suppresses type checking errors. It's advisable to resolve the underlying type issue to improve code quality. Ensure that the arguments passed to super().__init__ match the expected signature.

Apply this diff to remove the type ignore and fix any type issues:

-            super().__init__(*args, verbose=verbose, timeout=timeout, **kwargs)  # type: ignore
+            super().__init__(verbose=verbose, timeout=timeout, **kwargs)

62-62: Specify the type of self.sources instead of using # type: ignore

The # type: ignore suppresses type checking for self.sources. To enhance code clarity and maintainability, explicitly specify the type of self.sources.

Apply this diff to define the type of self.sources:

-        self.sources = []  # type: ignore
+        self.sources: List[Any] = []
templates/components/multiagent/python/app/workflows/tools.py (3)

21-24: Consider adding a docstring to the ContextAwareTool class.

While the class name is descriptive, it would be beneficial to provide a brief docstring explaining the purpose and usage of the ContextAwareTool class. This will improve the code's readability and maintainability.


68-96: Consider adding a docstring to the chat_with_tools function.

While the function name is descriptive, it would be beneficial to provide a more detailed docstring explaining the purpose, parameters, and return value of the chat_with_tools function. This will improve the code's readability and maintainability.


212-242: Consider adding a docstring to the _tool_call_generator function.

While the function name is descriptive, it would be beneficial to provide a docstring explaining the purpose, parameters, and yield values of the _tool_call_generator function. This will improve the code's readability and maintainability.

templates/components/agents/python/form_filling/app/workflows/form_filling.py (2)

76-88: Update docstring to accurately reflect the code

The docstring mentions tools like extract_question and answer_question, which differ from the actual tool names used (extractor_tool, filling_tool). Keeping the documentation in sync with the code enhances maintainability and clarity.

Update the docstring to match the actual tool names and workflow steps:

 Required tools:
-    - query_engine: A query engine to query for the answers to the questions.
-    - extract_question: Extract missing cells in a CSV file and generate questions to fill them.
-    - answer_question: Query for the answers to the questions.
+    - query_engine_tool: A query engine to find answers to the questions.
+    - extractor_tool: Extract missing cells in a CSV file and generate questions.
+    - filling_tool: Fill the missing cells with the answers.

 Flow:
     1. Extract missing cells in a CSV file and generate questions.
     2. Find answers to the questions using the query engine.
     3. Fill the missing cells with the answers.

227-232: Enhance event messages for consistency and clarity

In the fill_cells method, the event message "Filling missing cells" could be more descriptive to align with the previous events ("Extracting missing cells", "Finding answers for missing cells").

Consider rephrasing the message for clarity:

 ctx.write_event_to_stream(
     AgentRunEvent(
         name="Processor",
-        msg="Filling missing cells",
+        msg="Filling missing cells with answers",
     )
 )

This maintains consistency and provides a clearer description of the action being performed.

templates/components/agents/python/financial_report/app/workflows/financial_report.py (6)

112-114: Correct Grammatical Error in Assertion Message

The assertion message contains a grammatical error. Change "Try run generation script" to "Try running the generation script".

Apply this diff to fix the typo:

 ), "Query engine tool is not found. Try run generation script or upload a document file first."
+), "Query engine tool is not found. Try running the generation script or uploading a document file first."

91-92: Fix Grammatical Errors in _default_system_prompt

There are grammatical errors in the _default_system_prompt string.

  1. In line 91, change "You are a financial analyst who are given a set of tools to help you." to "You are a financial analyst who is given a set of tools to help you."

  2. In line 92, change "It's good to using appropriate tools" to "It's good to use appropriate tools."

Apply this diff:

 You are a financial analyst who are given a set of tools to help you.
+You are a financial analyst who is given a set of tools to help you.
 It's good to using appropriate tools for the user request and always use the information from the tools, don't make up anything yourself.
+It's good to use appropriate tools for the user request and always use the information from the tools; don't make up anything yourself.

234-236: Correct Grammatical Error in analysis_prompt

In the analysis_prompt string, there is a grammatical error in line 236. Change "you can asking for more information" to "you can ask for more information."

Apply this diff:

 If there is not enough information, you can asking for more information.
+If there is not enough information, you can ask for more information.

59-59: Ensure Consistent Use of Type Annotations

The code uses both list and List for type annotations. For consistency and compatibility with older Python versions, it's recommended to use List from the typing module.

Apply this diff:

 input: list[ToolSelection]
+input: List[ToolSelection]
 input: list[ToolSelection] | ChatMessage
+from typing import Union
+input: Union[List[ToolSelection], ChatMessage]
 chat_history: list[ChatMessage] = ev.input
+chat_history: List[ChatMessage] = ev.input

Also applies to: 63-63, 155-155


226-228: Clarify Type Checking in analyze Method

In the analyze method, the check isinstance(ev.input, list) may not be sufficient if ev.input can be other iterable types. Consider using isinstance(ev.input, List) or checking for Sequence for a more robust type check.

Apply this diff:

-event_requested_by_workflow_llm = isinstance(ev.input, list)
+from collections.abc import Sequence
+event_requested_by_workflow_llm = isinstance(ev.input, Sequence)

246-246: Remove Unnecessary Type Ignore Comment

The # type: ignore comment may be unnecessary if ev.input is correctly typed. If possible, adjust the code to avoid the need for this comment.

Apply this diff:

 chat_history.append(ev.input)  # type: ignore
+chat_history.append(ev.input)
📜 Review details

Configuration used: .coderabbit.yaml
Review profile: CHILL

📥 Commits

Reviewing files that changed from the base of the PR and between d79d165 and ee0c607.

📒 Files selected for processing (23)
  • .changeset/light-parrots-work.md (1 hunks)
  • e2e/shared/multiagent_template.spec.ts (2 hunks)
  • templates/components/agents/python/blog/README-template.md (1 hunks)
  • templates/components/agents/python/blog/app/workflows/__init__.py (1 hunks)
  • templates/components/agents/python/blog/app/workflows/blog.py (1 hunks)
  • templates/components/agents/python/blog/app/workflows/single.py (1 hunks)
  • templates/components/agents/python/financial_report/README-template.md (1 hunks)
  • templates/components/agents/python/financial_report/app/agents/analyst.py (0 hunks)
  • templates/components/agents/python/financial_report/app/agents/reporter.py (0 hunks)
  • templates/components/agents/python/financial_report/app/agents/researcher.py (0 hunks)
  • templates/components/agents/python/financial_report/app/agents/workflow.py (0 hunks)
  • templates/components/agents/python/financial_report/app/engine/engine.py (0 hunks)
  • templates/components/agents/python/financial_report/app/workflows/__init__.py (1 hunks)
  • templates/components/agents/python/financial_report/app/workflows/financial_report.py (1 hunks)
  • templates/components/agents/python/form_filling/README-template.md (1 hunks)
  • templates/components/agents/python/form_filling/app/agents/form_filling.py (0 hunks)
  • templates/components/agents/python/form_filling/app/engine/engine.py (0 hunks)
  • templates/components/agents/python/form_filling/app/workflows/__init__.py (1 hunks)
  • templates/components/agents/python/form_filling/app/workflows/form_filling.py (1 hunks)
  • templates/components/multiagent/python/app/api/routers/chat.py (2 hunks)
  • templates/components/multiagent/python/app/workflows/events.py (1 hunks)
  • templates/components/multiagent/python/app/workflows/function_calling_agent.py (1 hunks)
  • templates/components/multiagent/python/app/workflows/tools.py (1 hunks)
💤 Files with no reviewable changes (7)
  • templates/components/agents/python/financial_report/app/agents/analyst.py
  • templates/components/agents/python/financial_report/app/agents/reporter.py
  • templates/components/agents/python/financial_report/app/agents/researcher.py
  • templates/components/agents/python/financial_report/app/agents/workflow.py
  • templates/components/agents/python/financial_report/app/engine/engine.py
  • templates/components/agents/python/form_filling/app/agents/form_filling.py
  • templates/components/agents/python/form_filling/app/engine/engine.py
✅ Files skipped from review due to trivial changes (5)
  • .changeset/light-parrots-work.md
  • templates/components/agents/python/blog/README-template.md
  • templates/components/agents/python/financial_report/app/workflows/init.py
  • templates/components/agents/python/form_filling/README-template.md
  • templates/components/agents/python/form_filling/app/workflows/init.py
🧰 Additional context used
📓 Path-based instructions (10)
templates/components/agents/python/blog/app/workflows/__init__.py (1)

Pattern templates/**: For files under the templates folder, do not report 'Missing Dependencies Detected' errors.

templates/components/agents/python/blog/app/workflows/blog.py (1)

Pattern templates/**: For files under the templates folder, do not report 'Missing Dependencies Detected' errors.

templates/components/agents/python/blog/app/workflows/single.py (1)

Pattern templates/**: For files under the templates folder, do not report 'Missing Dependencies Detected' errors.

templates/components/agents/python/financial_report/README-template.md (1)

Pattern templates/**: For files under the templates folder, do not report 'Missing Dependencies Detected' errors.

templates/components/agents/python/financial_report/app/workflows/financial_report.py (1)

Pattern templates/**: For files under the templates folder, do not report 'Missing Dependencies Detected' errors.

templates/components/agents/python/form_filling/app/workflows/form_filling.py (1)

Pattern templates/**: For files under the templates folder, do not report 'Missing Dependencies Detected' errors.

templates/components/multiagent/python/app/api/routers/chat.py (1)

Pattern templates/**: For files under the templates folder, do not report 'Missing Dependencies Detected' errors.

templates/components/multiagent/python/app/workflows/events.py (1)

Pattern templates/**: For files under the templates folder, do not report 'Missing Dependencies Detected' errors.

templates/components/multiagent/python/app/workflows/function_calling_agent.py (1)

Pattern templates/**: For files under the templates folder, do not report 'Missing Dependencies Detected' errors.

templates/components/multiagent/python/app/workflows/tools.py (1)

Pattern templates/**: For files under the templates folder, do not report 'Missing Dependencies Detected' errors.

🔇 Additional comments (21)
templates/components/agents/python/blog/app/workflows/__init__.py (1)

1-3: LGTM! Clean module interface implementation.

The implementation follows Python best practices with explicit imports and exports. The module interface is well-structured and aligns with the PR's objective of enhancing workflow code.

templates/components/multiagent/python/app/workflows/events.py (1)

1-4: LGTM! Clean and minimal imports.

The imports are well-organized and specific to the requirements.

templates/components/agents/python/blog/app/workflows/blog.py (4)

7-7: LGTM! Clear and specific import alias.

The rename to create_blog_workflow improves clarity by making the import's purpose explicit and prevents naming conflicts with the local function.


14-16: LGTM! Function name better reflects its purpose.

The rename from get_chat_engine to create_workflow better represents the function's responsibility of creating workflow instances.


26-26: LGTM! Consistent with the import changes.

The use of create_blog_workflow is consistent with the import changes and maintains the same parameter passing pattern.


17-18: Consider tracking the chat filters implementation.

The comment indicates that chat filters are not supported yet. This should be tracked to ensure it's implemented in future updates.

Let's check if there's an existing issue tracking this:

Would you like me to create a new issue to track the chat filters implementation?

templates/components/agents/python/financial_report/README-template.md (1)

36-36: LGTM! Path update aligns with improved architecture.

The updated file path reflects a better organization structure by consolidating workflow-related code into a dedicated workflows directory. This change enhances code modularity and maintainability.

e2e/shared/multiagent_template.spec.ts (2)

21-21: LGTM: Addition of form_filling agent aligns with PR objectives

The addition of "form_filling" to templateAgents is consistent with the PR's goal of updating the form filling use case.


71-74: Clarify test coverage strategy for skipped agents

While the skip condition is clearly documented, skipping chat tests for both financial_report and form_filling agents raises some concerns:

  1. This reduces test coverage for core functionality
  2. There's no indication of when these tests will be implemented
  3. No alternative test approaches are suggested

Consider:

  • Adding a TODO with a timeline for implementing these tests
  • Documenting why chat tests aren't applicable for these agents
  • Implementing alternative test approaches if chat testing isn't suitable

Let's check if there are any existing alternative tests for these agents:

✅ Verification successful

Let me search for more specific test patterns and agent configurations to better understand the testing strategy.


Based on the search results, I can now provide a final response:

Skip condition is appropriate for these specialized agents

The skip condition is justified as these agents have specific purposes that don't align with chat-based testing:

  1. financial_report agent is configured with specialized tools (document_generator, interpreter) for financial report processing
  2. form_filling agent is designed specifically for form-filling workflows using the form_filling tool
  3. Both agents are properly tested through other means:
    • Basic frontend functionality is verified through the "Frontend should have a title" test
    • The agents have specific tool configurations and data sources (EXAMPLE_10K_SEC_FILES)
    • They are integrated into the template selection system with clear purposes
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Search for other test files related to these agents
fd -e spec.ts -e test.ts | xargs rg -l "financial_report|form_filling"

Length of output: 111


Script:

#!/bin/bash
# Search for agent configurations and test patterns
echo "=== Searching for agent configurations ==="
rg -A 5 "financial_report|form_filling" --type ts

echo -e "\n=== Searching for test patterns ==="
ast-grep --pattern 'test($$$, async ($$$) => { $$$ })'

Length of output: 20841

templates/components/multiagent/python/app/api/routers/chat.py (3)

7-8: Imports are correctly added

The imports for generate_filters and create_workflow are necessary and properly included.


30-33: Verify parameters passed to create_workflow

Ensure that chat_history, params, and filters are correctly formatted and meet the expected input requirements of create_workflow.


39-39: Ensure workflow.stream_events() provides the expected event sequence

Verify that workflow.stream_events() returns the correct events for streaming. If there are scenarios where it might return None or raise an exception, consider adding appropriate error handling to maintain the robustness of the application.

templates/components/multiagent/python/app/workflows/tools.py (5)

1-18: LGTM!

The imports are well-organized and follow the standard convention of grouping them by their source (standard library, third-party libraries, and local modules). The logger is also properly initialized.


27-34: LGTM!

The ResponseGenerator class is well-defined using the Pydantic BaseModel. The use of ConfigDict with arbitrary_types_allowed=True is appropriate for handling the AsyncGenerator type.


37-65: LGTM!

The ChatWithToolsResponse class is well-structured and provides useful methods for checking tool calls and generating full responses from asynchronous generators. The use of Pydantic's BaseModel ensures proper validation and serialization of the response data.


99-160: LGTM!

The call_tools function is well-implemented and handles multiple tool calls efficiently. The progress tracking and event emission logic is properly integrated. The error handling for non-existent tools is also appropriately managed.


163-209: LGTM!

The call_tool function is well-structured and handles the execution of individual tool calls effectively. The error handling and logging mechanisms are properly implemented. The distinction between ContextAwareTool and regular tools is correctly managed.

templates/components/agents/python/form_filling/app/workflows/form_filling.py (3)

160-167: Prevent potential infinite recursion in handle_llm_input

When the assistant detects tool call conflicts, it adds a message to self.memory and returns an InputEvent, which may cause handle_llm_input to be called repeatedly without resolving the issue, leading to an infinite loop.

Consider implementing a mechanism to track retries or limit the recursion depth. You might add a counter to the context to ensure the assistant eventually provides a final response or raises an exception after a certain number of attempts.


106-106: Initialization of system_prompt is appropriate

The assignment of self.system_prompt with a default ensures that a system prompt is always available. This approach is acceptable and follows good coding practices.


94-94: 🛠️ Refactor suggestion

Implement logic for missing query engine in system prompt scenario

The system prompt instructs the assistant to respond with a warning if the query engine tool is unavailable. However, the current implementation doesn't handle this case, which could lead to unexpected behavior.

Consider adding logic in the handle_llm_input method to check for the absence of the query engine tool and respond accordingly:

 if not response.has_tool_calls():
     return StopEvent(result=response.generator)
+if self.query_engine_tool is None and response.tool_name() == "<query_engine_tool_name>":
+    warning_message = "The query engine is not available. Please upload a different file or connect to a knowledge base."
+    self.memory.put(
+        ChatMessage(
+            role=MessageRole.ASSISTANT,
+            content=warning_message,
+        )
+    )
+    return StopEvent(result=self.memory.get())

This ensures the assistant behaves as intended when the query engine is not available.

Likely invalid or redundant comment.

templates/components/agents/python/financial_report/app/workflows/financial_report.py (1)

141-141: Ensure ev.input is Properly Typed

When adding the user input to memory, ensure that ev.input is a string. If ev.input can be of other types, consider converting it to a string or handling exceptions.

Run the following script to check the type of ev.input:

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 and nitpick comments (1)
templates/components/multiagent/python/app/workflows/function_calling_agent.py (1)

89-112: Consider simplifying the response handling logic.

The current implementation could be more concise by extracting the streaming response handling into a separate method.

Consider this refactoring:

     @step()
     async def handle_llm_input(
         self,
         ctx: Context,
         ev: InputEvent,
     ) -> ToolCallEvent | StopEvent:
         chat_history = ev.input
 
         response = await chat_with_tools(
             self.llm,
             self.tools,
             chat_history,
         )
         is_tool_call = isinstance(response, ToolCallResponse)
         if not is_tool_call:
-            if ctx.data["streaming"]:
-                return StopEvent(result=response)
-            else:
-                full_response = ""
-                async for chunk in response.generator:
-                    full_response += chunk.message.content
-                return StopEvent(result=full_response)
+            return await self._handle_response(response, ctx.data["streaming"])
         return ToolCallEvent(input=response)
+
+    async def _handle_response(self, response: Any, streaming: bool) -> StopEvent:
+        if streaming:
+            return StopEvent(result=response)
+        full_response = ""
+        async for chunk in response.generator:
+            full_response += chunk.message.content
+        return StopEvent(result=full_response)
📜 Review details

Configuration used: .coderabbit.yaml
Review profile: CHILL

📥 Commits

Reviewing files that changed from the base of the PR and between ee0c607 and 86cc257.

📒 Files selected for processing (1)
  • templates/components/multiagent/python/app/workflows/function_calling_agent.py (1 hunks)
🧰 Additional context used
📓 Path-based instructions (1)
templates/components/multiagent/python/app/workflows/function_calling_agent.py (1)

Pattern templates/**: For files under the templates folder, do not report 'Missing Dependencies Detected' errors.

🔇 Additional comments (4)
templates/components/multiagent/python/app/workflows/function_calling_agent.py (4)

1-26: LGTM! Well-structured imports and event class definitions.

The imports are properly organized and the event classes are concise and focused.


28-63: LGTM! Well-structured class initialization with proper type hints.

The constructor is well-organized with appropriate default values and type hints. The memory initialization using ChatMemoryBuffer is properly configured.

Note: The assert statement issue on line 55 was previously reported and should be addressed.


64-88: LGTM! Clear and well-structured chat history preparation.

The method follows a logical sequence of operations, properly handles system prompts, and manages event writing appropriately.


113-120: LGTM! Concise tool call handling.

The method effectively manages tool calls and memory updates in a clear and focused manner.

Note: The missing await for call_tools on line 118 was previously reported and should be addressed.

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

🧹 Outside diff range and nitpick comments (13)
templates/components/multiagent/python/app/workflows/function_calling_agent.py (4)

28-32: Enhance docstring with parameter descriptions.

The current docstring explains the purpose but lacks details about the parameters and their usage.

Add parameter descriptions like this:

 """
 A simple workflow to request LLM with tools independently.
 You can share the previous chat history to provide the context for the LLM.
+
+Args:
+    llm (FunctionCallingLLM): The language model supporting function calling.
+    chat_history (List[ChatMessage]): Optional previous chat messages.
+    tools (List[BaseTool]): Optional list of tools available to the agent.
+    system_prompt (str): Optional system prompt to set context.
+    verbose (bool): Whether to enable verbose logging.
+    timeout (float): Maximum time in seconds for workflow execution.
+    name (str): Name identifier for the agent.
+    write_events (bool): Whether to write workflow events.
 """

60-63: Add error handling for memory initialization.

The memory initialization could fail silently if the chat history is invalid.

Consider adding validation:

+        if chat_history is not None:
+            if not all(isinstance(msg, ChatMessage) for msg in chat_history):
+                raise ValueError("All items in chat_history must be ChatMessage objects")
         self.memory = ChatMemoryBuffer.from_defaults(
             llm=self.llm, chat_history=chat_history
         )

65-89: Add input validation for user messages.

The method should validate the user input before processing.

Consider adding validation:

         # get user input
         user_input = ev.input
+        if not isinstance(user_input, str) or not user_input.strip():
+            raise ValueError("User input must be a non-empty string")
         user_msg = ChatMessage(role="user", content=user_input)
         self.memory.put(user_msg)

108-111: Optimize streaming response handling.

The current implementation concatenates strings in a loop, which can be inefficient for large responses.

Consider using a list to collect chunks:

-                full_response = ""
+                chunks = []
                 async for chunk in response.generator:
-                    full_response += chunk.message.content
+                    chunks.append(chunk.message.content)
-                return StopEvent(result=full_response)
+                return StopEvent(result="".join(chunks))
templates/components/multiagent/python/app/workflows/tools.py (4)

23-23: Consider removing type ignore comment.

The type: ignore comment on the acall method might not be necessary. Consider specifying the exact type for the input parameter instead of using Any.


48-59: Consider adding docstrings to helper methods.

The helper methods is_calling_different_tools, has_tool_calls, and tool_name would benefit from docstrings explaining their purpose and return values.


68-68: Remove unnecessary type ignore comment.

The type: ignore comment on the chat_with_tools function seems unnecessary. Consider specifying proper type hints instead.


1-247: Consider adding comprehensive module documentation.

While the code is well-structured, it would benefit from:

  1. Module-level docstring explaining the overall purpose and architecture
  2. Examples of usage in docstrings
  3. Documentation of the progress tracking feature
🧰 Tools
🪛 Ruff

168-168: Function definition does not bind loop variable i

(B023)

templates/components/agents/python/form_filling/app/workflows/form_filling.py (5)

1-1: Add a docstring to describe the module's purpose.

It's a good practice to include a docstring at the beginning of each module to provide an overview of its functionality and any key details.

+"""
+This module defines the form filling workflow, which extracts missing cells from a CSV file, 
+finds answers to fill them using a query engine, and fills the missing cells with the answers.
+"""
 import os

59-62: Consider adding a description for the InputEvent class.

While the purpose of the InputEvent class can be inferred from its name and attributes, it would be helpful to include a brief description or docstring to clarify its role within the workflow.

 class InputEvent(Event):
+    """
+    Represents an input event in the form filling workflow.
+    """
     input: List[ChatMessage]
     response: bool = False

64-66: Consider adding a description for the ExtractMissingCellsEvent class.

Similar to the InputEvent class, adding a brief description or docstring for the ExtractMissingCellsEvent class would help clarify its purpose within the workflow.

 class ExtractMissingCellsEvent(Event):
+    """
+    Represents an event to extract missing cells from a CSV file.
+    """
     tool_calls: list[ToolSelection]

68-70: Consider adding a description for the FindAnswersEvent class.

To maintain consistency and improve code readability, consider adding a brief description or docstring for the FindAnswersEvent class.

 class FindAnswersEvent(Event):
+    """
+    Represents an event to find answers for missing cells.
+    """
     tool_calls: list[ToolSelection]

72-74: Consider adding a description for the FillEvent class.

For completeness and clarity, consider adding a brief description or docstring for the FillEvent class, similar to the other event classes.

 class FillEvent(Event):
+    """
+    Represents an event to fill missing cells with answers.
+    """
     tool_calls: list[ToolSelection]
📜 Review details

Configuration used: .coderabbit.yaml
Review profile: CHILL

📥 Commits

Reviewing files that changed from the base of the PR and between 86cc257 and eb55161.

📒 Files selected for processing (3)
  • templates/components/agents/python/form_filling/app/workflows/form_filling.py (1 hunks)
  • templates/components/multiagent/python/app/workflows/function_calling_agent.py (1 hunks)
  • templates/components/multiagent/python/app/workflows/tools.py (1 hunks)
🧰 Additional context used
📓 Path-based instructions (3)
templates/components/agents/python/form_filling/app/workflows/form_filling.py (1)

Pattern templates/**: For files under the templates folder, do not report 'Missing Dependencies Detected' errors.

templates/components/multiagent/python/app/workflows/function_calling_agent.py (1)

Pattern templates/**: For files under the templates folder, do not report 'Missing Dependencies Detected' errors.

templates/components/multiagent/python/app/workflows/tools.py (1)

Pattern templates/**: For files under the templates folder, do not report 'Missing Dependencies Detected' errors.

🪛 Ruff
templates/components/multiagent/python/app/workflows/tools.py

168-168: Function definition does not bind loop variable i

(B023)

🔇 Additional comments (10)
templates/components/multiagent/python/app/workflows/function_calling_agent.py (2)

1-26: LGTM! Clean imports and well-structured event classes.

The imports are well-organized and the event classes are concise with clear purposes.


119-119: ⚠️ Potential issue

Fix async call to call_tools.

The call_tools function is async and must be awaited.

Apply this fix:

-        tool_messages = call_tools(self.name, self.tools, ctx, tool_calls)
+        tool_messages = await call_tools(self.name, self.tools, ctx, tool_calls)
templates/components/multiagent/python/app/workflows/tools.py (1)

217-247: LGTM! Well-structured generator implementation.

The generator implementation correctly handles streaming responses and maintains clear state management. The boolean indicator pattern for tool calls is a clean approach.

templates/components/agents/python/form_filling/app/workflows/form_filling.py (7)

27-56: LGTM!

The create_workflow function is well-structured and handles the initialization of the workflow components effectively. It retrieves the index configuration, creates a query engine if an index is available, and sets up the necessary tools for extracting questions and filling forms using the ToolFactory. The function also allows for optional parameters such as chat history, configuration parameters, and filters, providing flexibility in workflow creation.


76-124: LGTM!

The FormFillingWorkflow class is well-documented with a clear description of its purpose, required tools, and the flow of the workflow. The initialization method handles the setup of the necessary tools, LLM, and memory buffer effectively. The class also includes a default system prompt to guide the assistant's behavior.


125-140: LGTM!

The start step is implemented correctly. It initializes the workflow by setting up the system prompt (if provided), adding the user input to the memory buffer, and returning an InputEvent with the chat history.


142-179: LGTM!

The handle_llm_input step is well-structured and handles the LLM input effectively. It processes the chat history, calls the appropriate tools based on the LLM's response, and returns the corresponding event (e.g., ExtractMissingCellsEvent, FillEvent, or StopEvent). The step also handles the case when the LLM tries to call different tools at the same time by adding an error message to the memory buffer and returning an InputEvent to prompt the LLM to process one step at a time.


180-202: LGTM!

The extract_missing_cells step is implemented correctly. It calls the extractor tool to extract missing cells from the CSV file, adds the tool messages to the memory buffer, and returns an InputEvent with the updated chat history.


203-221: LGTM!

The find_answers step is implemented correctly. It calls the query engine tool to find answers for the missing cells, adds the tool messages to the memory buffer, and returns an InputEvent with the updated chat history.


223-241: LGTM!

The fill_cells step is implemented correctly. It calls the filling tool to fill the missing cells with the answers, adds the tool messages to the memory buffer, and returns an InputEvent with the updated chat history.

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: 1

🧹 Outside diff range and nitpick comments (3)
templates/components/multiagent/python/app/workflows/tools.py (3)

68-97: Enhance function documentation.

While the function is well-implemented, consider expanding the docstring to include:

  • Parameter descriptions
  • Return value details
  • Example usage

Example docstring:

async def chat_with_tools(
    llm: FunctionCallingLLM,
    tools: list[BaseTool],
    chat_history: list[ChatMessage],
) -> ChatWithToolsResponse:
    """
    Request LLM to call tools or generate a response.
    
    Args:
        llm: The function-calling language model
        tools: List of available tools
        chat_history: Previous chat messages
        
    Returns:
        ChatWithToolsResponse containing either:
        - Tool calls and message if tools need to be called
        - Response generator for streaming regular chat responses
        
    This function doesn't modify the chat memory.
    """

99-164: Consider enhancing progress tracking.

The progress tracking implementation could be improved by:

  1. Adding a description of the current tool being called
  2. Including error state in progress data

Example enhancement:

 data={
     "id": progress_id,
     "total": total_steps,
     "current": current_step,
+    "description": f"Calling {tool_call.tool_name}",
+    "status": "in_progress"  # or "error" when exception occurs
 }
🧰 Tools
🪛 Ruff

158-158: Function definition does not bind loop variable i

(B023)


167-237: Consider improving type hints for better type safety.

The implementation is solid, but type safety could be enhanced:

  1. Remove # type: ignore comments by properly typing the parameters:
-    async def acall(self, ctx: Context, input: Any) -> ToolOutput:  # type: ignore
+    async def acall(self, ctx: Context, **kwargs: Any) -> ToolOutput:
  1. Use a more specific type for event_emitter:
-    event_emitter: Optional[Callable[[str], None]],
+    event_emitter: Optional[Callable[[str], None | Awaitable[None]]],
📜 Review details

Configuration used: .coderabbit.yaml
Review profile: CHILL

📥 Commits

Reviewing files that changed from the base of the PR and between eb55161 and 6e5486c.

📒 Files selected for processing (2)
  • e2e/shared/multiagent_template.spec.ts (2 hunks)
  • templates/components/multiagent/python/app/workflows/tools.py (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • e2e/shared/multiagent_template.spec.ts
🧰 Additional context used
📓 Path-based instructions (1)
templates/components/multiagent/python/app/workflows/tools.py (1)

Pattern templates/**: For files under the templates folder, do not report 'Missing Dependencies Detected' errors.

🪛 Ruff
templates/components/multiagent/python/app/workflows/tools.py

158-158: Function definition does not bind loop variable i

(B023)

🔇 Additional comments (1)
templates/components/multiagent/python/app/workflows/tools.py (1)

1-66: LGTM! Well-structured class definitions with proper type hints.

The class hierarchy and model definitions are well-organized with appropriate type hints, error handling, and edge case management.

@leehuwuj leehuwuj merged commit 6edea6a into main Nov 6, 2024
46 checks passed
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