[PR #208] [MERGED] feat: add max_invocation_timeout parameter #221

Closed
opened 2026-02-15 21:16:18 -05:00 by yindo · 0 comments
Owner

📋 Pull Request Information

Original PR: https://github.com/langgenius/dify-plugin-sdks/pull/208
Author: @Bytechoreographer
Created: 9/23/2025
Status: Merged
Merged: 9/26/2025
Merged by: @Yeuoly

Base: mainHead: feat/invocation_timeout_config


📝 Commits (2)

  • cdc8492 feat: add max_invocation_timeout parameter
  • d98b081 style: format MAX_INVOCATION_TIMEOUT description for better readability

📊 Changes

3 files changed (+15 additions, -4 deletions)

View changed files

📝 python/dify_plugin/config/config.py (+3 -0)
📝 python/dify_plugin/core/runtime.py (+11 -4)
📝 python/dify_plugin/plugin.py (+1 -0)

📄 Description

Plugin Invocation Timeout Configuration

Problem

Previously, the Dify Plugin SDK had a hardcoded timeout of 250 seconds for backwards invocations. When a plugin operation took longer than 250 seconds without receiving any response data, it would throw an exception:

invocation exited without response

This limitation affected plugins that needed to perform long-running operations such as:

  • Agent strategies using tools in sandbox environments with extended execution times
  • Large file processing
  • Complex AI model inference
  • External API calls with slow response times
  • Batch data processing operations

Solution

We've introduced a configurable timeout mechanism that allows developers to customize the invocation timeout based on their specific needs.

New Configuration Parameter

A new configuration parameter MAX_INVOCATION_TIMEOUT has been added to DifyPluginEnv:

class DifyPluginEnv(BaseSettings):
    MAX_INVOCATION_TIMEOUT: int = Field(
        default=250, 
        description="Maximum invocation timeout in seconds (for backwards invocation)"
    )
    # ... other fields

How It Works

  1. Configurable Timeout: Instead of the hardcoded 250-second limit, the system now uses the MAX_INVOCATION_TIMEOUT value from the configuration.

  2. Per-Plugin Configuration: Each plugin can set its own timeout value when initializing the DifyPluginEnv.

  3. Backwards Compatibility: The default value is 250 seconds, which is higher than the previous hardcoded 250 seconds, providing better default behavior.

  4. Dynamic Error Messages: Error messages now include the actual timeout value used for better debugging.

Usage Examples

Basic Usage with Custom Timeout

from dify_plugin import DifyPluginEnv, Plugin

# Configure plugin with 10-minute timeout
plugin = Plugin(DifyPluginEnv(
    MAX_INVOCATION_TIMEOUT=600  # 10 minutes
))

if __name__ == "__main__":
    plugin.run()

Environment Variable Configuration

You can also set the timeout via environment variables:

export MAX_INVOCATION_TIMEOUT=900  # 15 minutes

Different Scenarios

# For quick operations (5 minutes)
quick_plugin = Plugin(DifyPluginEnv(MAX_INVOCATION_TIMEOUT=250))

# For medium operations (10 minutes)  
medium_plugin = Plugin(DifyPluginEnv(MAX_INVOCATION_TIMEOUT=600))

# For long-running operations (30 minutes)
long_plugin = Plugin(DifyPluginEnv(MAX_INVOCATION_TIMEOUT=1800))

Technical Details

Implementation Changes

  1. Config Addition: Added MAX_INVOCATION_TIMEOUT to DifyPluginEnv class
  2. Session Enhancement: Enhanced Session class to accept and store the timeout value
  3. Runtime Logic: Modified _line_converter_wrapper method to use dynamic timeout
  4. Plugin Integration: Updated Plugin class to pass the configuration to sessions

Timeout Logic

The timeout mechanism works as follows:

  1. Each backwards invocation operation polls for responses with 1-second intervals
  2. When no response is received, an empty response counter is incremented
  3. When the counter reaches MAX_INVOCATION_TIMEOUT, the operation times out
  4. Any received response resets the counter to zero

Error Handling

When a timeout occurs, the system now provides more informative error messages:

invocation exited without response after {timeout_seconds} seconds

Migration Guide

For Existing Plugins

Existing plugins will continue to work without changes.

For New Plugins

New plugins can explicitly set their timeout requirements:

# Before (hardcoded 250s limit)
plugin = Plugin(DifyPluginEnv())

# After (configurable timeout)
plugin = Plugin(DifyPluginEnv(MAX_INVOCATION_TIMEOUT=custom_timeout))

Best Practices

  1. Choose Appropriate Timeouts: Set timeouts based on your plugin's expected maximum operation time
  2. Consider User Experience: Very long timeouts may impact user experience
  3. Monitor Performance: Keep track of your plugin's actual execution times
  4. Handle Timeouts Gracefully: Implement proper error handling for timeout scenarios
  5. Documentation: Document the recommended timeout settings for your plugin

Related Configuration

The timeout configuration works alongside other timeout settings:

  • MAX_REQUEST_TIMEOUT: HTTP request timeout (default: 250s)
  • MAX_INVOCATION_TIMEOUT: Backwards invocation timeout (default: 250s)

Both can be configured independently based on your plugin's needs.

Pull Request Checklist

Thank you for your contribution! Before submitting your PR, please make sure you have completed the following checks:

Compatibility Check

  • [✔] I have checked whether this change affects the backward compatibility of the plugin declared in README.md
  • [✔] I have checked whether this change affects the forward compatibility of the plugin declared in README.md
  • [✔] If this change introduces a breaking change, I have discussed it with the project maintainer and specified the release version in the README.md
  • [✔] I have described the compatibility impact and the corresponding version number in the PR description
  • [✔] I have checked whether the plugin version is updated in the README.md

Available Checks

  • [✔] Code has passed local tests
  • [✔] Relevant documentation has been updated (if necessary)

🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.

## 📋 Pull Request Information **Original PR:** https://github.com/langgenius/dify-plugin-sdks/pull/208 **Author:** [@Bytechoreographer](https://github.com/Bytechoreographer) **Created:** 9/23/2025 **Status:** ✅ Merged **Merged:** 9/26/2025 **Merged by:** [@Yeuoly](https://github.com/Yeuoly) **Base:** `main` ← **Head:** `feat/invocation_timeout_config` --- ### 📝 Commits (2) - [`cdc8492`](https://github.com/langgenius/dify-plugin-sdks/commit/cdc84924a2eda3c1fbf468038af2001499958b52) feat: add max_invocation_timeout parameter - [`d98b081`](https://github.com/langgenius/dify-plugin-sdks/commit/d98b081b65dca16f051ddbb3d924f0235c0c862a) style: format MAX_INVOCATION_TIMEOUT description for better readability ### 📊 Changes **3 files changed** (+15 additions, -4 deletions) <details> <summary>View changed files</summary> 📝 `python/dify_plugin/config/config.py` (+3 -0) 📝 `python/dify_plugin/core/runtime.py` (+11 -4) 📝 `python/dify_plugin/plugin.py` (+1 -0) </details> ### 📄 Description # Plugin Invocation Timeout Configuration ## Problem Previously, the Dify Plugin SDK had a hardcoded timeout of 250 seconds for backwards invocations. When a plugin operation took longer than 250 seconds without receiving any response data, it would throw an exception: ``` invocation exited without response ``` This limitation affected plugins that needed to perform long-running operations such as: - Agent strategies using tools in sandbox environments with extended execution times - Large file processing - Complex AI model inference - External API calls with slow response times - Batch data processing operations ## Solution We've introduced a configurable timeout mechanism that allows developers to customize the invocation timeout based on their specific needs. ### New Configuration Parameter A new configuration parameter `MAX_INVOCATION_TIMEOUT` has been added to `DifyPluginEnv`: ```python class DifyPluginEnv(BaseSettings): MAX_INVOCATION_TIMEOUT: int = Field( default=250, description="Maximum invocation timeout in seconds (for backwards invocation)" ) # ... other fields ``` ### How It Works 1. **Configurable Timeout**: Instead of the hardcoded 250-second limit, the system now uses the `MAX_INVOCATION_TIMEOUT` value from the configuration. 2. **Per-Plugin Configuration**: Each plugin can set its own timeout value when initializing the `DifyPluginEnv`. 3. **Backwards Compatibility**: The default value is 250 seconds, which is higher than the previous hardcoded 250 seconds, providing better default behavior. 4. **Dynamic Error Messages**: Error messages now include the actual timeout value used for better debugging. ## Usage Examples ### Basic Usage with Custom Timeout ```python from dify_plugin import DifyPluginEnv, Plugin # Configure plugin with 10-minute timeout plugin = Plugin(DifyPluginEnv( MAX_INVOCATION_TIMEOUT=600 # 10 minutes )) if __name__ == "__main__": plugin.run() ``` ### Environment Variable Configuration You can also set the timeout via environment variables: ```bash export MAX_INVOCATION_TIMEOUT=900 # 15 minutes ``` ### Different Scenarios ```python # For quick operations (5 minutes) quick_plugin = Plugin(DifyPluginEnv(MAX_INVOCATION_TIMEOUT=250)) # For medium operations (10 minutes) medium_plugin = Plugin(DifyPluginEnv(MAX_INVOCATION_TIMEOUT=600)) # For long-running operations (30 minutes) long_plugin = Plugin(DifyPluginEnv(MAX_INVOCATION_TIMEOUT=1800)) ``` ## Technical Details ### Implementation Changes 1. **Config Addition**: Added `MAX_INVOCATION_TIMEOUT` to `DifyPluginEnv` class 2. **Session Enhancement**: Enhanced `Session` class to accept and store the timeout value 3. **Runtime Logic**: Modified `_line_converter_wrapper` method to use dynamic timeout 4. **Plugin Integration**: Updated `Plugin` class to pass the configuration to sessions ### Timeout Logic The timeout mechanism works as follows: 1. Each backwards invocation operation polls for responses with 1-second intervals 2. When no response is received, an empty response counter is incremented 3. When the counter reaches `MAX_INVOCATION_TIMEOUT`, the operation times out 4. Any received response resets the counter to zero ### Error Handling When a timeout occurs, the system now provides more informative error messages: ``` invocation exited without response after {timeout_seconds} seconds ``` ## Migration Guide ### For Existing Plugins Existing plugins will continue to work without changes. ### For New Plugins New plugins can explicitly set their timeout requirements: ```python # Before (hardcoded 250s limit) plugin = Plugin(DifyPluginEnv()) # After (configurable timeout) plugin = Plugin(DifyPluginEnv(MAX_INVOCATION_TIMEOUT=custom_timeout)) ``` ## Best Practices 1. **Choose Appropriate Timeouts**: Set timeouts based on your plugin's expected maximum operation time 2. **Consider User Experience**: Very long timeouts may impact user experience 3. **Monitor Performance**: Keep track of your plugin's actual execution times 4. **Handle Timeouts Gracefully**: Implement proper error handling for timeout scenarios 5. **Documentation**: Document the recommended timeout settings for your plugin ## Related Configuration The timeout configuration works alongside other timeout settings: - `MAX_REQUEST_TIMEOUT`: HTTP request timeout (default: 250s) - `MAX_INVOCATION_TIMEOUT`: Backwards invocation timeout (default: 250s) Both can be configured independently based on your plugin's needs. # Pull Request Checklist Thank you for your contribution! Before submitting your PR, please make sure you have completed the following checks: ## Compatibility Check - [✔] I have checked whether this change affects the **backward compatibility** of the plugin declared in `README.md` - [✔] I have checked whether this change affects the **forward compatibility** of the plugin declared in `README.md` - [✔] If this change introduces a breaking change, I have discussed it with the project maintainer and specified the release version in the `README.md` - [✔] I have described the compatibility impact and the corresponding version number in the PR description - [✔] I have checked whether the plugin version is updated in the `README.md` ## Available Checks - [✔] Code has passed local tests - [✔] Relevant documentation has been updated (if necessary) --- <sub>🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.</sub>
yindo added the pull-request label 2026-02-15 21:16:18 -05:00
yindo closed this issue 2026-02-15 21:16:18 -05:00
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: langgenius/dify-plugin-sdks#221