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

Refactoring v3 mvp #1398

Merged
merged 6 commits into from
Feb 16, 2025
Merged

Conversation

chuanSir123
Copy link
Contributor

@chuanSir123 chuanSir123 commented Feb 15, 2025

Sourcery 总结

重构了工作流执行器、变量替换和帮助命令生成。引入了一个新的工作流用于直接存储聊天记忆以及一个相应的块。更新了回退调度规则以使用新的工作流。

新特性:

  • 引入了一个新的工作流 chat:directStore,它直接将用户消息存储到聊天记忆中,当其他调度规则未能匹配时,作为回退机制触发。此工作流简化了保存聊天历史记录的过程,并通过为未匹配的消息提供默认操作来改善用户体验。

增强功能:

  • 重构了工作流执行器,以确保在执行一个块之前,所有前置块都已完成。
  • 改进了 ChatMessageConstructor 块中的变量替换,以支持对象属性和字典键的访问。
  • 更新了帮助命令,以基于工作流类型对命令进行分类,并显示命令格式和描述。
  • 添加了一个新的 chat_memory_direct_store 块,用于直接存储聊天记忆。
  • ChatMessageConstructor 块中的系统提示中添加当前日期时间。
Original summary in English

Summary by Sourcery

Refactor the workflow executor, variable substitution, and help command generation. Introduce a new workflow for directly storing chat memory and a corresponding block. Update the fallback dispatch rule to use the new workflow.

New Features:

  • Introduce a new workflow chat:directStore that directly stores user messages to chat memory, triggered as a fallback mechanism when other dispatch rules fail to match. This workflow simplifies the process of saving chat history and improves the user experience by providing a default action for unmatched messages

Enhancements:

  • Refactor the workflow executor to ensure that all predecessor blocks are completed before executing a block.
  • Improve variable substitution in the ChatMessageConstructor block to support object properties and dictionary keys access.
  • Update the help command to categorize commands based on the workflow type and display the command format and description.
  • Add a new chat_memory_direct_store block to directly store chat memory.
  • Add current date time to system prompt in ChatMessageConstructor block

黄传 added 4 commits February 14, 2025 19:29
1. 改进工作流执行器逻辑:
- 优化block执行条件判断,确保所有前置blocks完成
- 改进输入收集机制,提高效率并增加错误检查

2. 更新调度规则配置:
- 将chat_normal规则类型从prefix改为keyword
- 添加新的关键词触发条件
- 修改fallback规则的工作流为directStore

3. 新增功能:
- 添加ChatMemoryDirectStore模块用于直接存储聊天记录
- 在聊天消息构造器中添加当前时间支持

4. 其他优化:
- 改进帮助信息生成逻辑
…ring-v3-mvp

# Conflicts:
#	framework/workflow/core/execution/executor.py
#	framework/workflow/implementations/blocks/llm/chat.py
#	framework/workflow/implementations/blocks/memory/chat_memory.py
#	framework/workflow/implementations/blocks/system/help.py
#	framework/workflow/implementations/blocks/system_blocks.py
Copy link
Contributor

sourcery-ai bot commented Feb 15, 2025

## Sourcery 评审者指南

此拉取请求引入了一个新的 `ChatMemoryDirectStore` 块,用于直接存储聊天消息;增强了 `ChatMessageConstructor` 块,使其支持动态变量替换;改进了 `WorkflowExecutor`,以实现更好的输入收集和执行控制;并标准化了 `GenerateHelp` 块中的类别命名。

#### ChatMemoryDirectStore 执行的序列图

```mermaid
sequenceDiagram
    participant User
    participant ChatMemoryDirectStore
    participant MemoryManager
    participant ScopeRegistry
    participant ComposerRegistry

    User->>ChatMemoryDirectStore: execute(user_msg: IMMessage)
    activate ChatMemoryDirectStore
    ChatMemoryDirectStore->>MemoryManager: resolve()
    activate MemoryManager
    deactivate MemoryManager
    ChatMemoryDirectStore->>ScopeRegistry: resolve()
    activate ScopeRegistry
    ChatMemoryDirectStore->>ScopeRegistry: get_scope(scope_type)
    activate ScopeRegistry
    deactivate ScopeRegistry
    deactivate ScopeRegistry
    ChatMemoryDirectStore->>ComposerRegistry: resolve()
    activate ComposerRegistry
    ChatMemoryDirectStore->>ComposerRegistry: get_composer("default")
    activate ComposerRegistry
    deactivate ComposerRegistry
    deactivate ComposerRegistry
    ChatMemoryDirectStore->>ComposerRegistry: compose(user_msg.sender, composed_messages)
    activate ComposerRegistry
    deactivate ComposerRegistry
    ChatMemoryDirectStore->>MemoryManager: store(scope, memory_entries)
    activate MemoryManager
    deactivate MemoryManager
    deactivate ChatMemoryDirectStore

带有变量替换的 ChatMessageConstructor 执行的序列图

sequenceDiagram
    participant ChatMessageConstructor
    participant WorkflowExecutor
    participant LLMChatMessage

    ChatMessageConstructor->>WorkflowExecutor: resolve()
    activate WorkflowExecutor
    deactivate WorkflowExecutor
    ChatMessageConstructor->>ChatMessageConstructor: substitute_variables(system_prompt_format, executor)
    activate ChatMessageConstructor
    ChatMessageConstructor->>WorkflowExecutor: get_variable(var_name, default)
    activate WorkflowExecutor
    deactivate WorkflowExecutor
    ChatMessageConstructor-->>ChatMessageConstructor: replace_var(match)
    deactivate ChatMessageConstructor
    ChatMessageConstructor->>ChatMessageConstructor: substitute_variables(user_prompt_format, executor)
    activate ChatMessageConstructor
    ChatMessageConstructor->>WorkflowExecutor: get_variable(var_name, default)
    activate WorkflowExecutor
    deactivate WorkflowExecutor
    ChatMessageConstructor-->>ChatMessageConstructor: replace_var(match)
    deactivate ChatMessageConstructor
    ChatMessageConstructor->>LLMChatMessage: Create LLMChatMessage(role='system', content=system_prompt)
    ChatMessageConstructor->>LLMChatMessage: Create LLMChatMessage(role='user', content=user_prompt)
    ChatMessageConstructor-->>ChatMessageConstructor: return llm_msg
Loading

文件级别变更

变更 详情 文件
引入了一个新的 ChatMemoryDirectStore 块,用于直接将聊天消息存储到内存中,而无需 LLM 响应。
  • implementations/blocks/memory/chat_memory.py 中添加了 ChatMemoryDirectStore 块。
  • implementations/blocks/system_blocks.py 中注册了 ChatMemoryDirectStore 块。
  • 创建了一个新的工作流 directStore.yaml 来使用 ChatMemoryDirectStore 块。
  • 更新了 rules.yaml 中的回退规则,以使用 directStore 工作流。
framework/workflow/implementations/blocks/memory/chat_memory.py
framework/workflow/implementations/blocks/system_blocks.py
data/dispatch_rules/rules.yaml
data/workflows/chat/directStore.yaml
增强了 ChatMessageConstructor 块,以支持提示中的动态变量替换,包括当前日期和时间。
  • 添加了 substitute_variables 方法来处理变量替换。
  • 修改了 execute 方法以使用 substitute_variables 进行提示格式化。
  • 添加了对 {current_date_time} 变量的支持。
framework/workflow/implementations/blocks/llm/chat.py
改进了 WorkflowExecutor,以增强输入收集和执行控制。
  • 重构了 _can_execute 以验证所有前置块是否已执行。
  • 重构了 _gather_inputs 以使用连线映射进行输入收集,并为缺少连线连接添加了错误处理。
framework/workflow/core/execution/executor.py
标准化了 GenerateHelp 块中的类别命名。
  • 将基于工作流名称的类别生成替换为 type_name
framework/workflow/implementations/blocks/system/help.py

提示和命令

与 Sourcery 互动

  • 触发新的审查: 在拉取请求上评论 @sourcery-ai review
  • 继续讨论: 直接回复 Sourcery 的审查评论。
  • 从审查评论生成 GitHub issue: 通过回复审查评论,要求 Sourcery 从评论中创建一个 issue。您也可以回复审查评论并使用 @sourcery-ai issue 从中创建一个 issue。
  • 生成拉取请求标题: 在拉取请求标题中的任何位置写入 @sourcery-ai 以随时生成标题。您也可以在拉取请求上评论 @sourcery-ai title 以随时(重新)生成标题。
  • 生成拉取请求摘要: 在拉取请求正文中的任何位置写入 @sourcery-ai summary 以随时在您想要的位置生成 PR 摘要。您也可以在拉取请求上评论 @sourcery-ai summary 以随时(重新)生成摘要。
  • 生成评审者指南: 在拉取请求上评论 @sourcery-ai guide 以随时(重新)生成评审者指南。
  • 解决所有 Sourcery 评论: 在拉取请求上评论 @sourcery-ai resolve 以解决所有 Sourcery 评论。如果您已经解决了所有评论并且不想再看到它们,这将非常有用。
  • 驳回所有 Sourcery 审查: 在拉取请求上评论 @sourcery-ai dismiss 以驳回所有现有的 Sourcery 审查。如果您想重新开始新的审查,这将特别有用 - 不要忘记评论 @sourcery-ai review 以触发新的审查!
  • 为 issue 生成行动计划: 在 issue 上评论 @sourcery-ai plan 以为其生成行动计划。

自定义您的体验

访问您的 仪表板 以:

  • 启用或禁用审查功能,例如 Sourcery 生成的拉取请求摘要、评审者指南等。
  • 更改审查语言。
  • 添加、删除或编辑自定义审查说明。
  • 调整其他审查设置。

获取帮助

```
Original review guide in English

Reviewer's Guide by Sourcery

This pull request introduces a new ChatMemoryDirectStore block for directly storing chat messages, enhances the ChatMessageConstructor block with dynamic variable substitution, improves the WorkflowExecutor for better input gathering and execution control, and standardizes category naming in the GenerateHelp block.

Sequence diagram for ChatMemoryDirectStore execution

sequenceDiagram
    participant User
    participant ChatMemoryDirectStore
    participant MemoryManager
    participant ScopeRegistry
    participant ComposerRegistry

    User->>ChatMemoryDirectStore: execute(user_msg: IMMessage)
    activate ChatMemoryDirectStore
    ChatMemoryDirectStore->>MemoryManager: resolve()
    activate MemoryManager
    deactivate MemoryManager
    ChatMemoryDirectStore->>ScopeRegistry: resolve()
    activate ScopeRegistry
    ChatMemoryDirectStore->>ScopeRegistry: get_scope(scope_type)
    activate ScopeRegistry
    deactivate ScopeRegistry
    deactivate ScopeRegistry
    ChatMemoryDirectStore->>ComposerRegistry: resolve()
    activate ComposerRegistry
    ChatMemoryDirectStore->>ComposerRegistry: get_composer("default")
    activate ComposerRegistry
    deactivate ComposerRegistry
    deactivate ComposerRegistry
    ChatMemoryDirectStore->>ComposerRegistry: compose(user_msg.sender, composed_messages)
    activate ComposerRegistry
    deactivate ComposerRegistry
    ChatMemoryDirectStore->>MemoryManager: store(scope, memory_entries)
    activate MemoryManager
    deactivate MemoryManager
    deactivate ChatMemoryDirectStore
Loading

Sequence diagram for ChatMessageConstructor execution with variable substitution

sequenceDiagram
    participant ChatMessageConstructor
    participant WorkflowExecutor
    participant LLMChatMessage

    ChatMessageConstructor->>WorkflowExecutor: resolve()
    activate WorkflowExecutor
    deactivate WorkflowExecutor
    ChatMessageConstructor->>ChatMessageConstructor: substitute_variables(system_prompt_format, executor)
    activate ChatMessageConstructor
    ChatMessageConstructor->>WorkflowExecutor: get_variable(var_name, default)
    activate WorkflowExecutor
    deactivate WorkflowExecutor
    ChatMessageConstructor-->>ChatMessageConstructor: replace_var(match)
    deactivate ChatMessageConstructor
    ChatMessageConstructor->>ChatMessageConstructor: substitute_variables(user_prompt_format, executor)
    activate ChatMessageConstructor
    ChatMessageConstructor->>WorkflowExecutor: get_variable(var_name, default)
    activate WorkflowExecutor
    deactivate WorkflowExecutor
    ChatMessageConstructor-->>ChatMessageConstructor: replace_var(match)
    deactivate ChatMessageConstructor
    ChatMessageConstructor->>LLMChatMessage: Create LLMChatMessage(role='system', content=system_prompt)
    ChatMessageConstructor->>LLMChatMessage: Create LLMChatMessage(role='user', content=user_prompt)
    ChatMessageConstructor-->>ChatMessageConstructor: return llm_msg
Loading

File-Level Changes

Change Details Files
Introduced a new ChatMemoryDirectStore block for directly storing chat messages into memory without requiring an LLM response.
  • Added ChatMemoryDirectStore block in implementations/blocks/memory/chat_memory.py.
  • Registered ChatMemoryDirectStore block in implementations/blocks/system_blocks.py.
  • Created a new workflow directStore.yaml to use the ChatMemoryDirectStore block.
  • Updated the fallback rule in rules.yaml to use the directStore workflow.
framework/workflow/implementations/blocks/memory/chat_memory.py
framework/workflow/implementations/blocks/system_blocks.py
data/dispatch_rules/rules.yaml
data/workflows/chat/directStore.yaml
Enhanced the ChatMessageConstructor block to support dynamic variable substitution in prompts, including current date and time.
  • Added substitute_variables method to handle variable substitution.
  • Modified the execute method to use substitute_variables for prompt formatting.
  • Added support for the {current_date_time} variable.
framework/workflow/implementations/blocks/llm/chat.py
Improved the WorkflowExecutor to enhance input gathering and execution control.
  • Refactored _can_execute to verify that all predecessor blocks have been executed.
  • Refactored _gather_inputs to use wire mappings for input collection and added error handling for missing wire connections.
framework/workflow/core/execution/executor.py
Standardized category naming in the GenerateHelp block.
  • Replaced workflow name based category generation with type_name.
framework/workflow/implementations/blocks/system/help.py

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!
  • Generate a plan of action for an issue: Comment @sourcery-ai plan on
    an issue to generate a plan of action for it.

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

Copy link
Contributor

@sourcery-ai sourcery-ai bot left a comment

Choose a reason for hiding this comment

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

@chuanSir123 - 我已经审查了你的更改 - 这里有一些反馈:

总体评论

  • 考虑将此 PR 中所做更改的描述添加到描述部分。
  • 包含对新的 ChatMemoryDirectStore 块的用途和用法的简要说明可能会有所帮助。
以下是我在审查期间查看的内容
  • 🟢 一般问题:一切看起来都不错
  • 🟢 安全性:一切看起来都不错
  • 🟢 测试:一切看起来都不错
  • 🟡 复杂性:发现 1 个问题
  • 🟢 文档:一切看起来都不错

Sourcery 对开源是免费的 - 如果您喜欢我们的评论,请考虑分享它们 ✨
帮助我更有用!请点击每个评论上的 👍 或 👎,我将使用反馈来改进您的评论。
Original comment in English

Hey @chuanSir123 - I've reviewed your changes - here's some feedback:

Overall Comments:

  • Consider adding a description of the changes made in this PR to the description section.
  • It might be helpful to include a brief explanation of the purpose and usage of the new ChatMemoryDirectStore block.
Here's what I looked at during the review
  • 🟢 General issues: all looks good
  • 🟢 Security: all looks good
  • 🟢 Testing: all looks good
  • 🟡 Complexity: 1 issue found
  • 🟢 Documentation: all looks good

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.


return {}
Copy link
Contributor

Choose a reason for hiding this comment

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

issue (complexity): 考虑将通用初始化逻辑提取到共享基类或辅助方法中,以减少代码重复。

现在您有三个类,它们具有几乎相同的逻辑来解析内存管理器、确定作用域和检索注册表。为了在不改变功能的情况下减少复杂性和重复,请考虑将通用初始化步骤提取到共享基类或辅助方法中。例如,您可以创建一个如下所示的基类:

class BaseChatMemoryStore(Block):
    container: DependencyContainer

    def __init__(self, scope_type: Optional[str] = None):
        self.scope_type = scope_type

    def setup_scope(self):
        self.memory_manager = self.container.resolve(MemoryManager)
        if self.scope_type is None:
            self.scope_type = self.memory_manager.config.default_scope
        scope_registry = self.container.resolve(ScopeRegistry)
        self.scope = scope_registry.get_scope(self.scope_type)

    def get_composer(self):
        composer_registry = self.container.resolve(ComposerRegistry)
        return composer_registry.get_composer("default")

然后更新您的 ChatMemoryStoreChatMemoryDirectStore 以从此基类继承。例如:

class ChatMemoryStore(BaseChatMemoryStore):
    name = "chat_memory_store"
    inputs = {
        "user_msg": Input("user_msg", "用户消息", IMMessage, "用户消息"),
        "llm_resp": Input("llm_resp", "LLM 响应", LLMChatResponse, "LLM 响应")
    }
    outputs = {}

    def execute(self, user_msg: IMMessage, llm_resp: LLMChatResponse) -> Dict[str, Any]:
        self.setup_scope()
        composer = self.get_composer()
        composed_messages = [user_msg]
        if llm_resp.choices and llm_resp.choices[0].message:
            composed_messages.append(llm_resp.choices[0].message)
        print(composed_messages)
        memory_entries = composer.compose(user_msg.sender, composed_messages)
        self.memory_manager.store(self.scope, memory_entries)
        return {}
class ChatMemoryDirectStore(BaseChatMemoryStore):
    name = "chat_memory_store"
    inputs = {"user_msg": Input("user_msg", IMMessage, "User message")}
    outputs = {}

    def execute(self, user_msg: IMMessage) -> Dict[str, Any]:
        self.setup_scope()
        composer = self.get_composer()
        composed_messages = [user_msg]
        print(composed_messages)
        memory_entries = composer.compose(user_msg.sender, composed_messages)
        self.memory_manager.store(self.scope, memory_entries)
        return {}

此重构保持所有功能完整,同时减少重复的代码块和整体复杂性。

Original comment in English

issue (complexity): Consider extracting the common initialization logic into a shared base class or helper methods to reduce code duplication.

You now have three classes with nearly identical logic for resolving the memory manager, determining the scope, and retrieving registries. To reduce complexity and duplication without altering functionality, consider extracting the common initialization steps into a shared base class or helper methods. For example, you might create a base class like this:

class BaseChatMemoryStore(Block):
    container: DependencyContainer

    def __init__(self, scope_type: Optional[str] = None):
        self.scope_type = scope_type

    def setup_scope(self):
        self.memory_manager = self.container.resolve(MemoryManager)
        if self.scope_type is None:
            self.scope_type = self.memory_manager.config.default_scope
        scope_registry = self.container.resolve(ScopeRegistry)
        self.scope = scope_registry.get_scope(self.scope_type)

    def get_composer(self):
        composer_registry = self.container.resolve(ComposerRegistry)
        return composer_registry.get_composer("default")

Then update your ChatMemoryStore and ChatMemoryDirectStore to inherit from this base class. For example:

class ChatMemoryStore(BaseChatMemoryStore):
    name = "chat_memory_store"
    inputs = {
        "user_msg": Input("user_msg", "用户消息", IMMessage, "用户消息"),
        "llm_resp": Input("llm_resp", "LLM 响应", LLMChatResponse, "LLM 响应")
    }
    outputs = {}

    def execute(self, user_msg: IMMessage, llm_resp: LLMChatResponse) -> Dict[str, Any]:
        self.setup_scope()
        composer = self.get_composer()
        composed_messages = [user_msg]
        if llm_resp.choices and llm_resp.choices[0].message:
            composed_messages.append(llm_resp.choices[0].message)
        print(composed_messages)
        memory_entries = composer.compose(user_msg.sender, composed_messages)
        self.memory_manager.store(self.scope, memory_entries)
        return {}
class ChatMemoryDirectStore(BaseChatMemoryStore):
    name = "chat_memory_store"
    inputs = {"user_msg": Input("user_msg", IMMessage, "User message")}
    outputs = {}

    def execute(self, user_msg: IMMessage) -> Dict[str, Any]:
        self.setup_scope()
        composer = self.get_composer()
        composed_messages = [user_msg]
        print(composed_messages)
        memory_entries = composer.compose(user_msg.sender, composed_messages)
        self.memory_manager.store(self.scope, memory_entries)
        return {}

This refactor keeps all functionality intact while reducing duplicated code blocks and overall complexity.

@lss233 lss233 merged commit 126cbda into lss233:refactoring-v3-mvp Feb 16, 2025
@lss233
Copy link
Owner

lss233 commented Feb 16, 2025

LGTM, thanks!

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