From e13bb1eb5fe4cf7845d314fd3ea3c66ee6cd9e17 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Mon, 30 Mar 2026 21:39:51 +0000 Subject: [PATCH] feat: implement unified deprecation management system MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Create centralized @deprecated decorator with version tracking - Add warn_deprecated_param() for consistent parameter warnings - Add MIGRATION.md with comprehensive deprecation guide - Update 7 key files to use unified deprecation system - Add version-based removal timeline (deprecated in 1.0.0, removed in 2.0.0) - Ensure backward compatibility with zero breaking changes - Add expiration detection for future CI integration Fixes #1135 🤖 Generated with [Claude Code](https://claude.ai/code) Co-authored-by: Mervin Praison --- MIGRATION.md | 238 ++++++++++++++++++ .../praisonaiagents/agent/agent.py | 73 +++--- .../praisonaiagents/agent/autonomy.py | 25 +- src/praisonai-agents/praisonaiagents/paths.py | 13 +- .../praisonaiagents/process/process.py | 13 +- .../praisonaiagents/task/task.py | 26 +- .../praisonaiagents/utils/__init__.py | 12 + .../praisonaiagents/utils/deprecation.py | 216 ++++++++++++++++ src/praisonai/praisonai/bots/_approval.py | 24 +- src/praisonai/praisonai/llm/__init__.py | 26 +- 10 files changed, 587 insertions(+), 79 deletions(-) create mode 100644 MIGRATION.md create mode 100644 src/praisonai-agents/praisonaiagents/utils/deprecation.py diff --git a/MIGRATION.md b/MIGRATION.md new file mode 100644 index 000000000..5e5f8605a --- /dev/null +++ b/MIGRATION.md @@ -0,0 +1,238 @@ +# Migration Guide + +This guide documents breaking changes and deprecations in PraisonAI, with migration instructions and timelines. + +## Version Strategy + +PraisonAI follows [Semantic Versioning](https://semver.org/): +- **Major versions** (e.g., 2.0.0): Breaking changes, deprecated features removed +- **Minor versions** (e.g., 1.5.0): New features, deprecations introduced +- **Patch versions** (e.g., 1.5.1): Bug fixes, no API changes + +**Deprecation Timeline:** +- Features are deprecated in **minor** releases +- Deprecated features are removed in the **next major** release +- Deprecation warnings include the removal version + +## Current Deprecations (v1.0.0) + +### Agent Parameters → Consolidated Config Objects + +**Status:** Deprecated in v1.0.0, will be removed in v2.0.0 + +Old standalone parameters have been consolidated into config objects for better organization and type safety. + +#### ❌ Old Way (Deprecated) +```python +from praisonaiagents import Agent + +agent = Agent( + name="coder", + allow_code_execution=True, # ❌ Deprecated + code_execution_mode="unsafe", # ❌ Deprecated + auto_save="my_session", # ❌ Deprecated + rate_limiter=my_limiter, # ❌ Deprecated + allow_delegation=True, # ❌ Deprecated + verification_hooks=[my_hook], # ❌ Deprecated + llm="gpt-4o-mini" # ❌ Deprecated +) +``` + +#### ✅ New Way (Recommended) +```python +from praisonaiagents import Agent, ExecutionConfig, MemoryConfig +from praisonaiagents.agent.autonomy import AutonomyConfig + +agent = Agent( + name="coder", + model="gpt-4o-mini", # ✅ Use 'model' instead of 'llm' + handoffs=[reviewer_agent], # ✅ Use 'handoffs' instead of 'allow_delegation' + execution=ExecutionConfig( + code_execution=True, + code_mode="unsafe", + rate_limiter=my_limiter + ), + memory=MemoryConfig(auto_save="my_session"), + autonomy=AutonomyConfig(verification_hooks=[my_hook]) +) +``` + +**Migration Steps:** +1. Replace `llm=` with `model=` +2. Replace `allow_delegation=True` with `handoffs=[agent_list]` +3. Group execution-related params into `ExecutionConfig` +4. Group memory params into `MemoryConfig` +5. Group autonomy params into `AutonomyConfig` + +### Task Parameters + +**Status:** Deprecated in v1.0.0, will be removed in v2.0.0 + +#### Task Callback → on_task_complete +```python +# ❌ Old Way +task = Task(callback=my_function) + +# ✅ New Way +task = Task(on_task_complete=my_function) +``` + +#### Task Guardrail → guardrails +```python +# ❌ Old Way +task = Task(guardrail=my_guardrail) + +# ✅ New Way +task = Task(guardrails=my_guardrail) +``` + +### Class Renames + +**Status:** Deprecated in v1.0.0, will be removed in v2.0.0 + +#### AutonomySignal → EscalationSignal +```python +# ❌ Old Way +from praisonaiagents.agent.autonomy import AutonomySignal + +# ✅ New Way +from praisonaiagents.escalation.types import EscalationSignal +``` + +### Directory Structure Changes + +**Status:** Deprecated in v1.0.0, will be removed in v2.0.0 + +#### Data Directory Migration +```bash +# Old location (deprecated) +~/.praisonai-data/ + +# New location (recommended) +~/.praisonai/ + +# Migration command +praisonai migrate-data +``` + +### Process Workflow → Workflow Class + +**Status:** Deprecated in v1.0.0, will be removed in v2.0.0 + +```python +# ❌ Old Way +from praisonaiagents import process +result = process='workflow' + +# ✅ New Way +from praisonaiagents import Workflow +workflow = Workflow(steps=[...]) +result = workflow.start() +``` + +### BotOS Platform Changes + +**Status:** Deprecated in v1.0.0, will be removed in v2.0.0 + +#### BotApprovalBackend → Platform-Specific Approvals +```python +# ❌ Old Way +from praisonai.bots._approval import BotApprovalBackend + +# ✅ New Way - Use platform-specific approvals +from praisonai.bots.approval import SlackApproval, TelegramApproval, DiscordApproval +``` + +### LLM Module Changes + +**Status:** Deprecated in v1.0.0, will be removed in v2.0.0 + +#### Embedding Function +```python +# ❌ Old Way +from praisonai.llm import embedding +result = embedding(text) + +# ✅ New Way +from praisonai import embed +# or +from praisonai.capabilities import embed +result = embed(text) # Returns EmbeddingResult with metadata +``` + +## Previous Versions + +### v0.9.x → v1.0.0 + +No breaking changes. All v0.9.x code continues to work with deprecation warnings. + +## Migration Tools + +### Automated Migration (Future) +We're working on automated migration tools: + +```bash +# Check for deprecated usage (Future) +praisonai check-deprecations + +# Auto-migrate code (Future) +praisonai migrate --from=1.0 --to=2.0 +``` + +### Manual Migration Checklist + +Before upgrading to v2.0.0: + +- [ ] Update Agent constructor parameters to use config objects +- [ ] Replace `llm=` with `model=` +- [ ] Update `allow_delegation` to `handoffs` +- [ ] Update task parameters (`callback` → `on_task_complete`, `guardrail` → `guardrails`) +- [ ] Replace `AutonomySignal` with `EscalationSignal` +- [ ] Migrate data directory with `praisonai migrate-data` +- [ ] Update workflow process to Workflow class +- [ ] Replace BotApprovalBackend with platform-specific approvals +- [ ] Update embedding imports +- [ ] Run tests to ensure functionality + +### Testing Your Migration + +After migrating: + +```bash +# Run with deprecation warnings as errors to catch any missed items +python -W error::DeprecationWarning your_script.py + +# Or use pytest +python -m pytest -W error::DeprecationWarning +``` + +## Getting Help + +- **Documentation:** Check the updated docs for new patterns +- **Examples:** See `/examples` for updated usage patterns +- **Community:** Ask questions in GitHub Discussions +- **Issues:** Report migration problems in GitHub Issues + +## Contributing + +When adding new deprecations: + +1. Use the `@deprecated` decorator from `praisonaiagents.utils.deprecation` +2. Specify `since` and `removal` versions +3. Provide clear `alternative` guidance +4. Update this MIGRATION.md file +5. Add deprecation to the test suite + +Example: +```python +from praisonaiagents.utils.deprecation import deprecated + +@deprecated( + since="1.5.0", + removal="2.0.0", + alternative="use new_function() instead", + details="The new function provides better error handling" +) +def old_function(): + pass +``` \ No newline at end of file diff --git a/src/praisonai-agents/praisonaiagents/agent/agent.py b/src/praisonai-agents/praisonaiagents/agent/agent.py index 5246d5d5a..6a86925c6 100644 --- a/src/praisonai-agents/praisonaiagents/agent/agent.py +++ b/src/praisonai-agents/praisonaiagents/agent/agent.py @@ -648,42 +648,55 @@ def __init__( # DEPRECATION WARNINGS for params consolidated into configs # Old params still work but emit warnings pointing to new API # ============================================================ - import warnings as _warnings + from ..utils.deprecation import warn_deprecated_param if allow_delegation: - _warnings.warn( - "Parameter 'allow_delegation' is deprecated. Use 'handoffs=[other_agent]' instead.", - DeprecationWarning, stacklevel=2, + warn_deprecated_param( + "allow_delegation", + since="1.0.0", + removal="2.0.0", + alternative="use 'handoffs=[other_agent]' instead", + stacklevel=3 ) if allow_code_execution: - _warnings.warn( - "Parameter 'allow_code_execution' is deprecated. " - "Use 'execution=ExecutionConfig(code_execution=True)' instead.", - DeprecationWarning, stacklevel=2, + warn_deprecated_param( + "allow_code_execution", + since="1.0.0", + removal="2.0.0", + alternative="use 'execution=ExecutionConfig(code_execution=True)' instead", + stacklevel=3 ) if code_execution_mode != "safe": - _warnings.warn( - "Parameter 'code_execution_mode' is deprecated. " - "Use 'execution=ExecutionConfig(code_mode=\"unsafe\")' instead.", - DeprecationWarning, stacklevel=2, + warn_deprecated_param( + "code_execution_mode", + since="1.0.0", + removal="2.0.0", + alternative='use \'execution=ExecutionConfig(code_mode="unsafe")\' instead', + stacklevel=3 ) if auto_save is not None: - _warnings.warn( - "Parameter 'auto_save' is deprecated. " - "Use 'memory=MemoryConfig(auto_save=\"name\")' instead.", - DeprecationWarning, stacklevel=2, + warn_deprecated_param( + "auto_save", + since="1.0.0", + removal="2.0.0", + alternative='use \'memory=MemoryConfig(auto_save="name")\' instead', + stacklevel=3 ) if rate_limiter is not None: - _warnings.warn( - "Parameter 'rate_limiter' is deprecated. " - "Use 'execution=ExecutionConfig(rate_limiter=obj)' instead.", - DeprecationWarning, stacklevel=2, + warn_deprecated_param( + "rate_limiter", + since="1.0.0", + removal="2.0.0", + alternative="use 'execution=ExecutionConfig(rate_limiter=obj)' instead", + stacklevel=3 ) if verification_hooks is not None: - _warnings.warn( - "Parameter 'verification_hooks' is deprecated. " - "Use 'autonomy=AutonomyConfig(verification_hooks=[...])' instead.", - DeprecationWarning, stacklevel=2, + warn_deprecated_param( + "verification_hooks", + since="1.0.0", + removal="2.0.0", + alternative="use 'autonomy=AutonomyConfig(verification_hooks=[...])' instead", + stacklevel=3 ) # ============================================================ @@ -1338,12 +1351,12 @@ def __init__( # Handle llm= deprecation: model= is the preferred parameter name # llm= still works but shows deprecation warning if llm is not None and model is None: - import warnings - warnings.warn( - "Parameter 'llm' is deprecated, use 'model' instead. " - "Example: Agent(model='gpt-4o-mini') instead of Agent(llm='gpt-4o-mini')", - DeprecationWarning, - stacklevel=2 + warn_deprecated_param( + "llm", + since="1.0.0", + removal="2.0.0", + alternative="use 'model' instead. Example: Agent(model='gpt-4o-mini')", + stacklevel=3 ) # model= is the preferred parameter (no warning) if model is not None: diff --git a/src/praisonai-agents/praisonaiagents/agent/autonomy.py b/src/praisonai-agents/praisonaiagents/agent/autonomy.py index 44c5076dd..d60cfed3c 100644 --- a/src/praisonai-agents/praisonaiagents/agent/autonomy.py +++ b/src/praisonai-agents/praisonaiagents/agent/autonomy.py @@ -215,23 +215,26 @@ class AutonomySignal(str, Enum): COMPLEX_KEYWORDS = "complex_keywords" def __init_subclass__(cls, **kwargs): - import warnings - warnings.warn( - "AutonomySignal is deprecated. Use EscalationSignal instead.", - DeprecationWarning, - stacklevel=2, + from ..utils.deprecation import warn_deprecated_param + warn_deprecated_param( + "AutonomySignal class", + since="1.0.0", + removal="2.0.0", + alternative="use EscalationSignal from praisonaiagents.escalation.types instead", + stacklevel=3 ) super().__init_subclass__(**kwargs) def _warn_autonomy_signal(): """Emit deprecation warning when AutonomySignal is accessed.""" - import warnings - warnings.warn( - "AutonomySignal is deprecated. Use EscalationSignal from " - "praisonaiagents.escalation.types instead.", - DeprecationWarning, - stacklevel=3, + from ..utils.deprecation import warn_deprecated_param + warn_deprecated_param( + "AutonomySignal", + since="1.0.0", + removal="2.0.0", + alternative="use EscalationSignal from praisonaiagents.escalation.types instead", + stacklevel=4 ) diff --git a/src/praisonai-agents/praisonaiagents/paths.py b/src/praisonai-agents/praisonaiagents/paths.py index 5bb2b7003..11eca5a25 100644 --- a/src/praisonai-agents/praisonaiagents/paths.py +++ b/src/praisonai-agents/praisonaiagents/paths.py @@ -90,11 +90,14 @@ def get_data_dir() -> Path: # Check legacy location (backward compat) legacy_path = home / LEGACY_DIR_NAME if legacy_path.exists(): - warnings.warn( - f"Using legacy data directory {legacy_path}. " - f"Run 'praisonai migrate-data' to migrate to {new_path}.", - DeprecationWarning, - stacklevel=2 + from .utils.deprecation import warn_deprecated_param + warn_deprecated_param( + "legacy data directory", + since="1.0.0", + removal="2.0.0", + alternative=f"run 'praisonai migrate-data' to migrate to {new_path}", + details=f"Using legacy directory {legacy_path}", + stacklevel=3 ) _data_dir_cache = legacy_path return legacy_path diff --git a/src/praisonai-agents/praisonaiagents/process/process.py b/src/praisonai-agents/praisonaiagents/process/process.py index 0f4689f5a..10edf5c61 100644 --- a/src/praisonai-agents/praisonaiagents/process/process.py +++ b/src/praisonai-agents/praisonaiagents/process/process.py @@ -867,12 +867,13 @@ def workflow(self): - Guardrails with validation feedback - Status tracking """ - import warnings - warnings.warn( - "process='workflow' is deprecated. Use the Workflow class instead: " - "from praisonaiagents import Workflow; workflow = Workflow(steps=[...]); workflow.start()", - DeprecationWarning, - stacklevel=2 + from ..utils.deprecation import warn_deprecated_param + warn_deprecated_param( + "process='workflow'", + since="1.0.0", + removal="2.0.0", + alternative="use the Workflow class instead: from praisonaiagents import Workflow; workflow = Workflow(steps=[...]); workflow.start()", + stacklevel=3 ) current_iter = 0 # Track how many times we've looped # Build workflow relationships first diff --git a/src/praisonai-agents/praisonaiagents/task/task.py b/src/praisonai-agents/praisonaiagents/task/task.py index 0b0f01858..1c705b616 100644 --- a/src/praisonai-agents/praisonaiagents/task/task.py +++ b/src/praisonai-agents/praisonaiagents/task/task.py @@ -167,12 +167,13 @@ def __init__( self.output_pydantic = output_pydantic # Handle callback/on_task_complete: on_task_complete is canonical, callback is deprecated if callback is not None and on_task_complete is None: - import warnings - warnings.warn( - "Parameter 'callback' is deprecated, use 'on_task_complete' instead. " - "Example: Task(on_task_complete=my_fn) instead of Task(callback=my_fn)", - DeprecationWarning, - stacklevel=2 + from ..utils.deprecation import warn_deprecated_param + warn_deprecated_param( + "callback", + since="1.0.0", + removal="2.0.0", + alternative="use 'on_task_complete' instead. Example: Task(on_task_complete=my_fn)", + stacklevel=3 ) self.callback = callback elif callback is not None and on_task_complete is not None: @@ -198,12 +199,13 @@ def __init__( self.retain_full_context = retain_full_context # Handle guardrail/guardrails: guardrails (plural) is canonical, guardrail (singular) is deprecated if guardrail is not None and guardrails is None: - import warnings - warnings.warn( - "Parameter 'guardrail' is deprecated, use 'guardrails' instead. " - "Example: Task(guardrails=my_fn) instead of Task(guardrail=my_fn)", - DeprecationWarning, - stacklevel=2 + from ..utils.deprecation import warn_deprecated_param + warn_deprecated_param( + "guardrail", + since="1.0.0", + removal="2.0.0", + alternative="use 'guardrails' instead. Example: Task(guardrails=my_fn)", + stacklevel=3 ) # guardrails takes precedence over guardrail self.guardrail = guardrails if guardrails is not None else guardrail diff --git a/src/praisonai-agents/praisonaiagents/utils/__init__.py b/src/praisonai-agents/praisonaiagents/utils/__init__.py index 5af8642e9..878d3d19c 100644 --- a/src/praisonai-agents/praisonaiagents/utils/__init__.py +++ b/src/praisonai-agents/praisonaiagents/utils/__init__.py @@ -28,6 +28,13 @@ substitute_variables, ) +from .deprecation import ( + deprecated, + warn_deprecated_param, + DeprecationConfig, + check_expired_deprecations, +) + __all__ = [ # Protocol "DynamicVariableProvider", @@ -46,4 +53,9 @@ "resolve_dynamic_variable", # Shared utility "substitute_variables", + # Deprecation utilities + "deprecated", + "warn_deprecated_param", + "DeprecationConfig", + "check_expired_deprecations", ] diff --git a/src/praisonai-agents/praisonaiagents/utils/deprecation.py b/src/praisonai-agents/praisonaiagents/utils/deprecation.py new file mode 100644 index 000000000..f8130fa00 --- /dev/null +++ b/src/praisonai-agents/praisonaiagents/utils/deprecation.py @@ -0,0 +1,216 @@ +""" +Unified deprecation management for PraisonAI. + +This module provides a centralized @deprecated decorator with version tracking, +consistent messaging, and migration guidance following AGENTS.md principles. +""" + +import warnings +import functools +from typing import Optional, Union, Callable, Any +import inspect + +__all__ = ['deprecated', 'DeprecationConfig', 'check_expired_deprecations'] + +class DeprecationConfig: + """Configuration for deprecation behavior and version management.""" + + # Current version for deprecation tracking + CURRENT_VERSION = "1.0.0" + + # Show stack traces for deprecation warnings (useful for debugging) + SHOW_STACKLEVEL = True + + # Warn about expired deprecations that should be removed + WARN_EXPIRED = True + + +def _parse_version(version_str: str) -> tuple[int, ...]: + """Parse version string into comparable tuple.""" + if not version_str: + return (0,) + return tuple(int(x) for x in version_str.split('.')) + + +def _is_version_expired(removal_version: str, current_version: str) -> bool: + """Check if a deprecation has passed its removal version.""" + if not removal_version or not current_version: + return False + return _parse_version(current_version) >= _parse_version(removal_version) + + +def deprecated( + since: str, + removal: Optional[str] = None, + alternative: Optional[str] = None, + details: Optional[str] = None, + category: type[Warning] = DeprecationWarning +) -> Callable: + """ + Decorator to mark functions, methods, or classes as deprecated. + + Args: + since: Version when the feature was deprecated (e.g., "1.5.0") + removal: Version when the feature will be removed (e.g., "2.0.0") + alternative: Suggested replacement (e.g., "use new_function() instead") + details: Additional migration guidance + category: Warning category (default: DeprecationWarning) + + Example: + @deprecated( + since="1.5.0", + removal="2.0.0", + alternative="use Agent(model='gpt-4') instead", + details="The new API provides better type safety and validation" + ) + def old_function(): + pass + """ + def decorator(func_or_class: Callable) -> Callable: + # Build deprecation message + name = getattr(func_or_class, '__name__', str(func_or_class)) + + # Check if this deprecation has expired + if removal and DeprecationConfig.WARN_EXPIRED: + if _is_version_expired(removal, DeprecationConfig.CURRENT_VERSION): + expired_msg = ( + f"EXPIRED DEPRECATION: {name} was scheduled for removal in " + f"v{removal} but current version is v{DeprecationConfig.CURRENT_VERSION}. " + f"This should be removed from the codebase." + ) + warnings.warn(expired_msg, category=UserWarning, stacklevel=2) + + # Build user-facing deprecation message + msg_parts = [f"{name} is deprecated since v{since}"] + + if removal: + msg_parts.append(f"and will be removed in v{removal}") + + if alternative: + msg_parts.append(f". {alternative}") + elif removal: + msg_parts.append(".") + else: + msg_parts.append(".") + + if details: + msg_parts.append(f" {details}") + + message = "".join(msg_parts) + + # Handle class deprecation + if inspect.isclass(func_or_class): + original_init = func_or_class.__init__ + + @functools.wraps(original_init) + def new_init(self, *args, **kwargs): + stacklevel = 3 if DeprecationConfig.SHOW_STACKLEVEL else 2 + warnings.warn(message, category=category, stacklevel=stacklevel) + return original_init(self, *args, **kwargs) + + func_or_class.__init__ = new_init + return func_or_class + + # Handle function/method deprecation + @functools.wraps(func_or_class) + def wrapper(*args, **kwargs): + stacklevel = 3 if DeprecationConfig.SHOW_STACKLEVEL else 2 + warnings.warn(message, category=category, stacklevel=stacklevel) + return func_or_class(*args, **kwargs) + + return wrapper + + return decorator + + +def warn_deprecated_param( + param_name: str, + since: str, + removal: Optional[str] = None, + alternative: Optional[str] = None, + details: Optional[str] = None, + stacklevel: int = 2 +) -> None: + """ + Emit a deprecation warning for a specific parameter. + + Use this for parameter deprecations in function/method bodies. + + Args: + param_name: Name of the deprecated parameter + since: Version when parameter was deprecated + removal: Version when parameter will be removed + alternative: Suggested replacement + details: Additional migration guidance + stacklevel: Stack level for warning (default: 2) + + Example: + def my_function(old_param=None, new_param=None): + if old_param is not None: + warn_deprecated_param( + "old_param", + since="1.5.0", + removal="2.0.0", + alternative="use new_param instead" + ) + """ + # Check if this deprecation has expired + if removal and DeprecationConfig.WARN_EXPIRED: + if _is_version_expired(removal, DeprecationConfig.CURRENT_VERSION): + expired_msg = ( + f"EXPIRED DEPRECATION: Parameter '{param_name}' was scheduled " + f"for removal in v{removal} but current version is " + f"v{DeprecationConfig.CURRENT_VERSION}. This should be removed." + ) + warnings.warn(expired_msg, category=UserWarning, stacklevel=stacklevel) + + # Build deprecation message + msg_parts = [f"Parameter '{param_name}' is deprecated since v{since}"] + + if removal: + msg_parts.append(f" and will be removed in v{removal}") + + if alternative: + msg_parts.append(f". {alternative}") + elif removal: + msg_parts.append(".") + else: + msg_parts.append(".") + + if details: + msg_parts.append(f" {details}") + + message = "".join(msg_parts) + + warnings.warn(message, category=DeprecationWarning, stacklevel=stacklevel) + + +def check_expired_deprecations(current_version: Optional[str] = None) -> list[str]: + """ + Check for expired deprecations in the codebase. + + This function can be used in CI to detect deprecations that should be removed. + + Args: + current_version: Override for current version (defaults to DeprecationConfig.CURRENT_VERSION) + + Returns: + List of expired deprecation messages + """ + # This is a placeholder for CI integration + # In practice, this would scan the codebase for @deprecated decorators + # and check their removal versions against the current version + if current_version is None: + current_version = DeprecationConfig.CURRENT_VERSION + + expired = [] + + # TODO: Add scanning logic here for CI integration + # This would use AST parsing to find all @deprecated decorators + # and check if their removal versions have passed + + return expired + + +# Backward compatibility alias for existing code +warn = warn_deprecated_param \ No newline at end of file diff --git a/src/praisonai/praisonai/bots/_approval.py b/src/praisonai/praisonai/bots/_approval.py index a835119ea..d02f828ed 100644 --- a/src/praisonai/praisonai/bots/_approval.py +++ b/src/praisonai/praisonai/bots/_approval.py @@ -11,13 +11,23 @@ import logging # Module-level deprecation warning -import warnings as _deprecation_warnings -_deprecation_warnings.warn( - "BotApprovalBackend is deprecated. Use platform-specific approval backends " - "(SlackApproval, TelegramApproval, DiscordApproval, WebhookApproval, HTTPApproval) instead.", - DeprecationWarning, - stacklevel=2 -) +try: + from praisonaiagents.utils.deprecation import warn_deprecated_param + warn_deprecated_param( + "BotApprovalBackend module", + since="1.0.0", + removal="2.0.0", + alternative="use platform-specific approval backends (SlackApproval, TelegramApproval, DiscordApproval, WebhookApproval, HTTPApproval) instead", + stacklevel=2 + ) +except ImportError: + # Fallback if deprecation module not available + import warnings as _deprecation_warnings + _deprecation_warnings.warn( + "BotApprovalBackend is deprecated. Use platform-specific approval backends instead.", + DeprecationWarning, + stacklevel=2 + ) import time from typing import Any, Dict diff --git a/src/praisonai/praisonai/llm/__init__.py b/src/praisonai/praisonai/llm/__init__.py index e75940852..f9b9bc536 100644 --- a/src/praisonai/praisonai/llm/__init__.py +++ b/src/praisonai/praisonai/llm/__init__.py @@ -98,14 +98,24 @@ def embedding(text, model="text-embedding-3-small", **kwargs): Note: Requires litellm. Install with: pip install praisonai[llm] """ - import warnings - warnings.warn( - "praisonai.llm.embedding() is deprecated. " - "Use 'from praisonai import embed' or 'from praisonai.capabilities import embed' instead. " - "The new embed() returns EmbeddingResult with metadata.", - DeprecationWarning, - stacklevel=2 - ) + try: + from praisonaiagents.utils.deprecation import warn_deprecated_param + warn_deprecated_param( + "praisonai.llm.embedding()", + since="1.0.0", + removal="2.0.0", + alternative="use 'from praisonai import embed' or 'from praisonai.capabilities import embed' instead", + details="The new embed() returns EmbeddingResult with metadata", + stacklevel=3 + ) + except ImportError: + # Fallback if deprecation module not available + import warnings + warnings.warn( + "praisonai.llm.embedding() is deprecated. Use 'from praisonai import embed' instead.", + DeprecationWarning, + stacklevel=2 + ) try: import litellm