Update an existing tool with new configuration and create a new version Args: tool_cls: New tool class with updated implementation tool_config_dict: Configuration dict for tool initialization If None, will try to get from global config
(self,
tool_cls: Type[Tool],
tool_config_dict: Optional[Dict[str, Any]] = None,
new_version: Optional[str] = None,
description: Optional[str] = None,
code: Optional[str] = None)
| 546 | return [name for name in self._tool_configs.keys()] |
| 547 | |
| 548 | async def update(self, |
| 549 | tool_cls: Type[Tool], |
| 550 | tool_config_dict: Optional[Dict[str, Any]] = None, |
| 551 | new_version: Optional[str] = None, |
| 552 | description: Optional[str] = None, |
| 553 | code: Optional[str] = None) -> ToolConfig: |
| 554 | """Update an existing tool with new configuration and create a new version |
| 555 | |
| 556 | Args: |
| 557 | tool_cls: New tool class with updated implementation |
| 558 | tool_config_dict: Configuration dict for tool initialization |
| 559 | If None, will try to get from global config |
| 560 | new_version: New version string. If None, auto-increments from current version. |
| 561 | description: Description for this version update |
| 562 | code: Optional source code string. If provided, uses this instead of extracting from tool_cls. |
| 563 | This is useful when tool_cls is dynamically created from code string. |
| 564 | |
| 565 | Returns: |
| 566 | ToolConfig: Updated tool configuration |
| 567 | """ |
| 568 | try: |
| 569 | if tool_config_dict is None: |
| 570 | # Fallback to global config by class name |
| 571 | tool_config_key = inflection.underscore(tool_cls.__name__) |
| 572 | tool_config_dict = config.get(tool_config_key, {}) |
| 573 | |
| 574 | # Instantiate tool immediately (update is a runtime operation) |
| 575 | try: |
| 576 | tool_instance = tool_cls(**tool_config_dict) |
| 577 | except Exception as e: |
| 578 | logger.error(f"| ❌ Failed to create tool instance for {tool_cls.__name__}: {e}") |
| 579 | raise ValueError(f"Failed to instantiate tool {tool_cls.__name__} with provided config: {e}") |
| 580 | |
| 581 | tool_name = tool_instance.name |
| 582 | |
| 583 | # Check if tool exists |
| 584 | original_config = self._tool_configs.get(tool_name) |
| 585 | if original_config is None: |
| 586 | raise ValueError(f"Tool {tool_name} not found. Use register() to register a new tool.") |
| 587 | |
| 588 | tool_description = tool_instance.description |
| 589 | tool_metadata = tool_instance.metadata |
| 590 | # Get require_grad from tool_config_dict if provided, otherwise from tool_instance |
| 591 | tool_require_grad = tool_config_dict.get("require_grad", tool_instance.require_grad) if tool_config_dict and "require_grad" in tool_config_dict else tool_instance.require_grad |
| 592 | |
| 593 | # Determine new version from version_manager |
| 594 | if new_version is None: |
| 595 | # Get current version from version_manager and generate next patch version |
| 596 | new_version = await version_manager.generate_next_version("tool", tool_name, "patch") |
| 597 | |
| 598 | # Get tool code - use provided code if available (for dynamically created classes) |
| 599 | if code is not None: |
| 600 | tool_code = code |
| 601 | else: |
| 602 | tool_code = dynamic_manager.get_source_code(tool_cls) |
| 603 | if not tool_code: |
| 604 | logger.warning(f"| ⚠️ Tool {tool_name} is dynamic but source code cannot be extracted") |
| 605 |
no test coverage detected