@ -123,6 +123,7 @@ class Runnable(Generic[Input, Output], ABC):
other : Union [
Runnable [ Any , Other ] ,
Callable [ [ Any ] , Other ] ,
Callable [ [ Iterator [ Any ] ] , Iterator [ Other ] ] ,
Mapping [ str , Union [ Runnable [ Any , Other ] , Callable [ [ Any ] , Other ] , Any ] ] ,
] ,
) - > RunnableSequence [ Input , Other ] :
@ -132,7 +133,8 @@ class Runnable(Generic[Input, Output], ABC):
self ,
other : Union [
Runnable [ Other , Any ] ,
Callable [ [ Any ] , Other ] ,
Callable [ [ Other ] , Any ] ,
Callable [ [ Iterator [ Other ] ] , Iterator [ Any ] ] ,
Mapping [ str , Union [ Runnable [ Other , Any ] , Callable [ [ Other ] , Any ] , Any ] ] ,
] ,
) - > RunnableSequence [ Other , Output ] :
@ -353,7 +355,7 @@ class Runnable(Generic[Input, Output], ABC):
else :
# Make a best effort to gather, for any type that supports `+`
# This method should throw an error if gathering fails.
final += chunk # type: ignore[operator]
final = final + chunk # type: ignore[operator]
if got_first_val :
yield from self . stream ( final , config , * * kwargs )
@ -379,7 +381,7 @@ class Runnable(Generic[Input, Output], ABC):
else :
# Make a best effort to gather, for any type that supports `+`
# This method should throw an error if gathering fails.
final += chunk # type: ignore[operator]
final = final + chunk # type: ignore[operator]
if got_first_val :
async for output in self . astream ( final , config , * * kwargs ) :
@ -453,6 +455,7 @@ class Runnable(Generic[Input, Output], ABC):
input : Input ,
config : Optional [ RunnableConfig ] ,
run_type : Optional [ str ] = None ,
* * kwargs : Optional [ Any ] ,
) - > Output :
""" Helper method to transform an Input value to an Output value,
with callbacks . Use this method to implement invoke ( ) in subclasses . """
@ -465,7 +468,9 @@ class Runnable(Generic[Input, Output], ABC):
name = config . get ( " run_name " ) ,
)
try :
output = call_func_with_variable_args ( func , input , run_manager , config )
output = call_func_with_variable_args (
func , input , run_manager , config , * * kwargs
)
except BaseException as e :
run_manager . on_chain_error ( e )
raise
@ -486,6 +491,7 @@ class Runnable(Generic[Input, Output], ABC):
input : Input ,
config : Optional [ RunnableConfig ] ,
run_type : Optional [ str ] = None ,
* * kwargs : Optional [ Any ] ,
) - > Output :
""" Helper method to transform an Input value to an Output value,
with callbacks . Use this method to implement ainvoke ( ) in subclasses . """
@ -499,7 +505,7 @@ class Runnable(Generic[Input, Output], ABC):
)
try :
output = await acall_func_with_variable_args (
func , input , run_manager , config
func , input , run_manager , config , * * kwargs
)
except BaseException as e :
await run_manager . on_chain_error ( e )
@ -526,6 +532,7 @@ class Runnable(Generic[Input, Output], ABC):
* ,
return_exceptions : bool = False ,
run_type : Optional [ str ] = None ,
* * kwargs : Optional [ Any ] ,
) - > List [ Output ] :
""" Helper method to transform an Input value to an Output value,
with callbacks . Use this method to implement invoke ( ) in subclasses . """
@ -546,7 +553,6 @@ class Runnable(Generic[Input, Output], ABC):
)
]
try :
kwargs : Dict [ str , Any ] = { }
if accepts_config ( func ) :
kwargs [ " config " ] = [
patch_config ( c , callbacks = rm . get_child ( ) )
@ -597,6 +603,7 @@ class Runnable(Generic[Input, Output], ABC):
* ,
return_exceptions : bool = False ,
run_type : Optional [ str ] = None ,
* * kwargs : Optional [ Any ] ,
) - > List [ Output ] :
""" Helper method to transform an Input value to an Output value,
with callbacks . Use this method to implement invoke ( ) in subclasses . """
@ -619,7 +626,6 @@ class Runnable(Generic[Input, Output], ABC):
)
)
try :
kwargs : Dict [ str , Any ] = { }
if accepts_config ( func ) :
kwargs [ " config " ] = [
patch_config ( c , callbacks = rm . get_child ( ) )
@ -668,6 +674,7 @@ class Runnable(Generic[Input, Output], ABC):
] ,
config : Optional [ RunnableConfig ] ,
run_type : Optional [ str ] = None ,
* * kwargs : Optional [ Any ] ,
) - > Iterator [ Output ] :
""" Helper method to transform an Iterator of Input values into an Iterator of
Output values , with callbacks .
@ -689,7 +696,6 @@ class Runnable(Generic[Input, Output], ABC):
name = config . get ( " run_name " ) ,
)
try :
kwargs : Dict [ str , Any ] = { }
if accepts_config ( transformer ) :
kwargs [ " config " ] = patch_config (
config , callbacks = run_manager . get_child ( )
@ -706,7 +712,7 @@ class Runnable(Generic[Input, Output], ABC):
final_output = chunk
else :
try :
final_output += chunk # type: ignore[operator]
final_output = final_output + chunk # type: ignore
except TypeError :
final_output = None
final_output_supported = False
@ -716,7 +722,7 @@ class Runnable(Generic[Input, Output], ABC):
final_input = ichunk
else :
try :
final_input += ichunk # type: ignore[operator]
final_input = final_input + ichunk # type: ignore
except TypeError :
final_input = None
final_input_supported = False
@ -746,6 +752,7 @@ class Runnable(Generic[Input, Output], ABC):
] ,
config : Optional [ RunnableConfig ] ,
run_type : Optional [ str ] = None ,
* * kwargs : Optional [ Any ] ,
) - > AsyncIterator [ Output ] :
""" Helper method to transform an Async Iterator of Input values into an Async
Iterator of Output values , with callbacks .
@ -767,7 +774,6 @@ class Runnable(Generic[Input, Output], ABC):
name = config . get ( " run_name " ) ,
)
try :
kwargs : Dict [ str , Any ] = { }
if accepts_config ( transformer ) :
kwargs [ " config " ] = patch_config (
config , callbacks = run_manager . get_child ( )
@ -784,7 +790,7 @@ class Runnable(Generic[Input, Output], ABC):
final_output = chunk
else :
try :
final_output += chunk # type: ignore[operator]
final_output = final_output + chunk # type: ignore
except TypeError :
final_output = None
final_output_supported = False
@ -794,7 +800,7 @@ class Runnable(Generic[Input, Output], ABC):
final_input = ichunk
else :
try :
final_input += ichunk # type: ignore[operator]
final_input = final_input + ichunk # type: ignore[operator]
except TypeError :
final_input = None
final_input_supported = False
@ -1311,6 +1317,7 @@ class RunnableSequence(Serializable, Runnable[Input, Output]):
other : Union [
Runnable [ Any , Other ] ,
Callable [ [ Any ] , Other ] ,
Callable [ [ Iterator [ Any ] ] , Iterator [ Other ] ] ,
Mapping [ str , Union [ Runnable [ Any , Other ] , Callable [ [ Any ] , Other ] , Any ] ] ,
] ,
) - > RunnableSequence [ Input , Other ] :
@ -1331,7 +1338,8 @@ class RunnableSequence(Serializable, Runnable[Input, Output]):
self ,
other : Union [
Runnable [ Other , Any ] ,
Callable [ [ Any ] , Other ] ,
Callable [ [ Other ] , Any ] ,
Callable [ [ Iterator [ Other ] ] , Iterator [ Any ] ] ,
Mapping [ str , Union [ Runnable [ Other , Any ] , Callable [ [ Other ] , Any ] , Any ] ] ,
] ,
) - > RunnableSequence [ Other , Output ] :
@ -1751,7 +1759,7 @@ class RunnableMapChunk(Dict[str, Any]):
if key not in chunk or chunk [ key ] is None :
chunk [ key ] = other [ key ]
elif other [ key ] is not None :
chunk [ key ] += other [ key ]
chunk [ key ] = chunk [ key ] + other [ key ]
return chunk
def __radd__ ( self , other : RunnableMapChunk ) - > RunnableMapChunk :
@ -1760,7 +1768,7 @@ class RunnableMapChunk(Dict[str, Any]):
if key not in chunk or chunk [ key ] is None :
chunk [ key ] = self [ key ]
elif self [ key ] is not None :
chunk [ key ] += self [ key ]
chunk [ key ] = chunk [ key ] + self [ key ]
return chunk
@ -2061,6 +2069,139 @@ class RunnableMap(Serializable, Runnable[Input, Dict[str, Any]]):
yield chunk
class RunnableGenerator ( Runnable [ Input , Output ] ) :
"""
A runnable that runs a generator function .
"""
def __init__ (
self ,
transform : Union [
Callable [ [ Iterator [ Input ] ] , Iterator [ Output ] ] ,
Callable [ [ AsyncIterator [ Input ] ] , AsyncIterator [ Output ] ] ,
] ,
atransform : Optional [
Callable [ [ AsyncIterator [ Input ] ] , AsyncIterator [ Output ] ]
] = None ,
) - > None :
if atransform is not None :
self . _atransform = atransform
if inspect . isasyncgenfunction ( transform ) :
self . _atransform = transform
elif inspect . isgeneratorfunction ( transform ) :
self . _transform = transform
else :
raise TypeError (
" Expected a generator function type for `transform`. "
f " Instead got an unsupported type: { type ( transform ) } "
)
@property
def InputType ( self ) - > Any :
func = getattr ( self , " _transform " , None ) or getattr ( self , " _atransform " )
try :
params = inspect . signature ( func ) . parameters
first_param = next ( iter ( params . values ( ) ) , None )
if first_param and first_param . annotation != inspect . Parameter . empty :
return getattr ( first_param . annotation , " __args__ " , ( Any , ) ) [ 0 ]
else :
return Any
except ValueError :
return Any
@property
def OutputType ( self ) - > Any :
func = getattr ( self , " _transform " , None ) or getattr ( self , " _atransform " )
try :
sig = inspect . signature ( func )
return (
getattr ( sig . return_annotation , " __args__ " , ( Any , ) ) [ 0 ]
if sig . return_annotation != inspect . Signature . empty
else Any
)
except ValueError :
return Any
def __eq__ ( self , other : Any ) - > bool :
if isinstance ( other , RunnableGenerator ) :
if hasattr ( self , " _transform " ) and hasattr ( other , " _transform " ) :
return self . _transform == other . _transform
elif hasattr ( self , " _atransform " ) and hasattr ( other , " _atransform " ) :
return self . _atransform == other . _atransform
else :
return False
else :
return False
def __repr__ ( self ) - > str :
return " RunnableGenerator(...) "
def transform (
self ,
input : Iterator [ Input ] ,
config : Optional [ RunnableConfig ] = None ,
* * kwargs : Any ,
) - > Iterator [ Output ] :
return self . _transform_stream_with_config (
input , self . _transform , config , * * kwargs
)
def stream (
self ,
input : Input ,
config : Optional [ RunnableConfig ] = None ,
* * kwargs : Any ,
) - > Iterator [ Output ] :
return self . transform ( iter ( [ input ] ) , config , * * kwargs )
def invoke (
self , input : Input , config : Optional [ RunnableConfig ] = None , * * kwargs : Any
) - > Output :
final = None
for output in self . stream ( input , config , * * kwargs ) :
if final is None :
final = output
else :
final = final + output
return cast ( Output , final )
def atransform (
self ,
input : AsyncIterator [ Input ] ,
config : Optional [ RunnableConfig ] = None ,
* * kwargs : Any ,
) - > AsyncIterator [ Output ] :
if not hasattr ( self , " _atransform " ) :
raise NotImplementedError ( " This runnable does not support async methods. " )
return self . _atransform_stream_with_config (
input , self . _atransform , config , * * kwargs
)
def astream (
self ,
input : Input ,
config : Optional [ RunnableConfig ] = None ,
* * kwargs : Any ,
) - > AsyncIterator [ Output ] :
async def input_aiter ( ) - > AsyncIterator [ Input ] :
yield input
return self . atransform ( input_aiter ( ) , config , * * kwargs )
async def ainvoke (
self , input : Input , config : Optional [ RunnableConfig ] = None , * * kwargs : Any
) - > Output :
final = None
async for output in self . astream ( input , config , * * kwargs ) :
if final is None :
final = output
else :
final = final + output
return cast ( Output , final )
class RunnableLambda ( Runnable [ Input , Output ] ) :
"""
A runnable that runs a callable .
@ -2538,6 +2679,8 @@ RunnableLike = Union[
Runnable [ Input , Output ] ,
Callable [ [ Input ] , Output ] ,
Callable [ [ Input ] , Awaitable [ Output ] ] ,
Callable [ [ Iterator [ Input ] ] , Iterator [ Output ] ] ,
Callable [ [ AsyncIterator [ Input ] ] , AsyncIterator [ Output ] ] ,
Mapping [ str , Any ] ,
]
@ -2545,8 +2688,10 @@ RunnableLike = Union[
def coerce_to_runnable ( thing : RunnableLike ) - > Runnable [ Input , Output ] :
if isinstance ( thing , Runnable ) :
return thing
elif inspect . isasyncgenfunction ( thing ) or inspect . isgeneratorfunction ( thing ) :
return RunnableGenerator ( thing )
elif callable ( thing ) :
return RunnableLambda ( thing )
return RunnableLambda ( cast( Callable [ [ Input ] , Output ] , thing) )
elif isinstance ( thing , dict ) :
runnables : Mapping [ str , Runnable [ Any , Any ] ] = {
key : coerce_to_runnable ( r ) for key , r in thing . items ( )