# orchestra/__init__.py

from ._version import __version__
from .adapters.langgraph import EnhancedLangGraph, OrchestraConfig
from .adapters.langchain import EnhancedLangChain

def enhance(target, config=None):
    """
    Enhance a LangGraph or LangChain object with semantic caching.
    
    Args:
        target: The object to enhance (LangGraph CompiledGraph, LangChain Chain, or Runnable)
        config: Configuration object (optional)
        
    Returns:
        Enhanced object (EnhancedLangGraph or EnhancedLangChain)
    """
    # 1. Detect LangGraph
    # We check for class name string to avoid strict dependency imports if not needed
    target_type = type(target).__name__
    
    # Heuristic: Check for LangGraph specific attributes
    # LangGraph CompiledGraph usually has .stream / .astream and comes from langgraph
    if hasattr(target, "stream") and hasattr(target, "astream") and "Graph" in target_type:
         return EnhancedLangGraph(target, config)

    # 2. Detect LangChain
    # Chains often have .run or .invoke
    if hasattr(target, "invoke") or hasattr(target, "run"):
        return EnhancedLangChain(target, config)
        
    # Default/Fallback
    # If we can't tell, we assume it's a generic Runnable (LangChain style)
    return EnhancedLangChain(target, config)

__all__ = ["enhance", "OrchestraConfig", "EnhancedLangGraph", "EnhancedLangChain", "__version__"]
