Actions¶
- class burr.core.action.Action¶
-
- __init__()¶
Represents an action in a state machine. This is the base class from which actions extend. Note that this class needs to have a name set after the fact.
- get_source() str ¶
Returns the source code of the action. This will default to the source code of the class in which the action is implemented, but can be overwritten.” Override if you want debugging/tracking to display a different source
- input_schema() Any ¶
Returns the input schema for the action. The input schema is a type that can be used to validate the input to the action
- property inputs: list[str] | tuple[list[str], list[str]]¶
Represents inputs that are used for this to run. These correspond to the
**run_kwargs
in run above.Note that this has two possible return values: 1. A list of strings – these are the keys that are required to run the function 2. A tuple of two lists of strings – the first list is the required keys, the second is the optional keys
- Returns:
Either a list of strings (required inputs) or a tuple of two lists of strings (required and optional inputs)
- is_async() bool ¶
Convenience method to check if the function is async or not. This can be used by the application to run it.
- Returns:
True if the function is async, False otherwise
- property name: str¶
Gives the name of this action. This should be unique across your application.
- property optional_and_required_inputs: tuple[set[str], set[str]]¶
Returns a tuple of two sets of strings – the first set is the required keys, the second is the optional keys. This is internal and not meant to override.
- Returns:
Tuple of required keys and optional keys
- abstract property reads: list[str]¶
Returns the keys from the state that this function reads
- Returns:
A list of keys
- abstract run(state: State, **run_kwargs) dict ¶
Runs the function on the given state and returns the result. The result is just a key/value dictionary.
- Parameters:
state – State to run the function on
run_kwargs – Additional arguments to the function passed at runtime.
- Returns:
Result of the function
- abstract update(result: dict, state: State) State ¶
Performs a state update given a result and the current state. Returns a new, modified
State
(recall state is immutable – simply changing the state in place will not work).In the context of Burr, this is only applied in the two-step actions, where the
run
and update() functions are separate. The function-based APIs for Burr use the SingleStepAction class, which performs them both at once. This is not (yet) exposed as an interface for users to extend.- Parameters:
result – Result of a function executing on the state
state – State to update
- Returns:
A new, modified state.
- validate_inputs(inputs: Dict[str, Any] | None) None ¶
Validates the inputs to the function. This is a convenience method to allow for validation of inputs before running the function.
- Parameters:
inputs – Inputs to validate
- Raises:
ValueError – If the inputs are invalid
- with_name(name: str) Self ¶
Returns a copy of the given action with the given name. Why do we need this? We instantiate actions without names, and then set them later. This is a way to make the API cleaner/consolidate it, and the ApplicationBuilder will end up handling it for you, in the with_actions(…) method, which is the only way to use actions.
Note they can also take in names in the constructor for testing, but otherwise this is not something users will ever have to think about.
- Parameters:
name – Name to set
- Returns:
A new action with the given name
- abstract property writes: list[str]¶
Returns the keys from the state that this reducer writes.
- Returns:
A list of keys
- class burr.core.action.Result(*fields: str)¶
- __init__(*fields: str)¶
Represents a result action. This is purely a convenience class to pull data from state and give it out to the result. It does nothing to the state itself.
- Parameters:
fields – Fields to pull from the state and put into results
- property reads: list[str]¶
Returns the keys from the state that this function reads
- Returns:
A list of keys
- run(state: State) dict ¶
Runs the function on the given state and returns the result. The result is just a key/value dictionary.
- Parameters:
state – State to run the function on
run_kwargs – Additional arguments to the function passed at runtime.
- Returns:
Result of the function
- update(result: dict, state: State) State ¶
Performs a state update given a result and the current state. Returns a new, modified
State
(recall state is immutable – simply changing the state in place will not work).In the context of Burr, this is only applied in the two-step actions, where the
run
and update() functions are separate. The function-based APIs for Burr use the SingleStepAction class, which performs them both at once. This is not (yet) exposed as an interface for users to extend.- Parameters:
result – Result of a function executing on the state
state – State to update
- Returns:
A new, modified state.
- property writes: list[str]¶
Returns the keys from the state that this reducer writes.
- Returns:
A list of keys
- class burr.core.action.Input(*fields: str)¶
- __init__(*fields: str)¶
Represents an input action – this reads something from an input then writes that directly to state. This is a convenience class for when you don’t need to process the input and just want to put it in state for later use.
- Parameters:
fields – Fields to pull from the inputs and put into state
- property inputs: list[str]¶
Represents inputs that are used for this to run. These correspond to the
**run_kwargs
in run above.Note that this has two possible return values: 1. A list of strings – these are the keys that are required to run the function 2. A tuple of two lists of strings – the first list is the required keys, the second is the optional keys
- Returns:
Either a list of strings (required inputs) or a tuple of two lists of strings (required and optional inputs)
- property reads: list[str]¶
Returns the keys from the state that this function reads
- Returns:
A list of keys
- run(state: State, **run_kwargs) dict ¶
Runs the function on the given state and returns the result. The result is just a key/value dictionary.
- Parameters:
state – State to run the function on
run_kwargs – Additional arguments to the function passed at runtime.
- Returns:
Result of the function
- update(result: dict, state: State) State ¶
Performs a state update given a result and the current state. Returns a new, modified
State
(recall state is immutable – simply changing the state in place will not work).In the context of Burr, this is only applied in the two-step actions, where the
run
and update() functions are separate. The function-based APIs for Burr use the SingleStepAction class, which performs them both at once. This is not (yet) exposed as an interface for users to extend.- Parameters:
result – Result of a function executing on the state
state – State to update
- Returns:
A new, modified state.
- property writes: list[str]¶
Returns the keys from the state that this reducer writes.
- Returns:
A list of keys
- class burr.core.action.action(reads: List[str], writes: List[str])¶
- __init__(reads: List[str], writes: List[str])¶
Decorator to create a function-based action. This is user-facing. Note that, in the future, with typed state, we may not need this for all cases.
If parameters are not bound, they will be interpreted as inputs and must be passed in at runtime. If they have default values, they will be recorded as optional inputs. These can (optionally) be provided at runtime.
- Parameters:
reads – Items to read from the state
writes – Items to write to the state
- Returns:
The decorator to assign the function as an action
- static pydantic(
- reads: List[str],
- writes: List[str],
- state_input_type: Type[BaseModel] | None = None,
- state_output_type: Type[BaseModel] | None = None,
Action that specifies inputs/outputs using pydantic models. This should make it easier to develop with guardrails.
- Parameters:
reads – keys that this model reads. Note that this will be a subset of the pydantic model with which this is decorated. We will be validating that the keys are present in the model.
writes – keys that this model writes. Note that this will be a subset of the pydantic model with which this is decorated. We will be validating that the keys are present in the model.
state_input_type – The pydantic model type that is used to represent the input state. If this is None it will attempt to derive from the signature.
state_output_type – The pydantic model type that is used to represent the output state. If this is None it will attempt to derive from the signature.
- Returns:
- burr.core.action.bind(
- self: FunctionRepresentingAction,
- **kwargs: Any,
Binds an action to the given parameters. This is functionally equivalent to functools.partial, but is more explicit and is meant to be used in the API. This only works with the
@action
functional API and not with the class-based API.@action(["x"], ["y"]) def my_action(state: State, z: int) -> tuple[dict, State]: return {"y": state.get("x") + z}, state my_action.bind(z=2)
- Parameters:
self – The decorated function
kwargs – The keyword arguments to bind
- Returns:
The decorated function with the given parameters bound
- class burr.core.action.Function¶
Interface to represent the ‘computing’ part of an action
- property inputs: list[str] | tuple[list[str], list[str]]¶
Represents inputs that are used for this to run. These correspond to the
**run_kwargs
in run above.Note that this has two possible return values: 1. A list of strings – these are the keys that are required to run the function 2. A tuple of two lists of strings – the first list is the required keys, the second is the optional keys
- Returns:
Either a list of strings (required inputs) or a tuple of two lists of strings (required and optional inputs)
- is_async() bool ¶
Convenience method to check if the function is async or not. This can be used by the application to run it.
- Returns:
True if the function is async, False otherwise
- property optional_and_required_inputs: tuple[set[str], set[str]]¶
Returns a tuple of two sets of strings – the first set is the required keys, the second is the optional keys. This is internal and not meant to override.
- Returns:
Tuple of required keys and optional keys
- abstract property reads: list[str]¶
Returns the keys from the state that this function reads
- Returns:
A list of keys
- abstract run(state: State, **run_kwargs) dict ¶
Runs the function on the given state and returns the result. The result is just a key/value dictionary.
- Parameters:
state – State to run the function on
run_kwargs – Additional arguments to the function passed at runtime.
- Returns:
Result of the function
- validate_inputs(inputs: Dict[str, Any] | None) None ¶
Validates the inputs to the function. This is a convenience method to allow for validation of inputs before running the function.
- Parameters:
inputs – Inputs to validate
- Raises:
ValueError – If the inputs are invalid
- class burr.core.action.Reducer¶
Interface to represent the ‘updating’ part of an action
- abstract update(result: dict, state: State) State ¶
Performs a state update given a result and the current state. Returns a new, modified
State
(recall state is immutable – simply changing the state in place will not work).In the context of Burr, this is only applied in the two-step actions, where the
run
and update() functions are separate. The function-based APIs for Burr use the SingleStepAction class, which performs them both at once. This is not (yet) exposed as an interface for users to extend.- Parameters:
result – Result of a function executing on the state
state – State to update
- Returns:
A new, modified state.
- abstract property writes: list[str]¶
Returns the keys from the state that this reducer writes.
- Returns:
A list of keys
- class burr.core.action.StreamingResultContainer(
- streaming_result_generator: Generator[Tuple[dict, State[StateType] | None], None, None],
- initial_state: State[StateType],
- process_result: Callable[[dict, State], tuple[dict, State]],
- callback: Callable[[dict | None, State, Exception | None], None],
Container for a streaming result. This allows you to:
Iterate over the result as it comes in
Get the final result/state at the end
If you’re familiar with generators/iterators in python, this is effectively an iterator that caches the final result after calling it. This is meant to be used exclusively with the streaming action calls in Application. Note that you will never instantiate this class directly, but you will use it in the API when it is returned by
stream_result
. For reference, here’s how you would use it:action_we_just_ran, streaming_result_container = application.stream_result(...) print(f"getting streaming results for action={action_we_just_ran.name}") for result_component in streaming_result_container: print(result_component['response']) # this assumes you have a response key in your result final_result, final_state = streaming_result_container.get()
- static pass_through(
- results: StreamResultType,
- final_state: State[StateType],
Instantiates a streaming result container that just passes through the given results This is to be used internally – it allows us to wrap non-streaming action results in a streaming result container.
- class burr.core.action.AsyncStreamingResultContainer(
- streaming_result_generator: AsyncGenerator[Tuple[dict, State[StateType] | None], None],
- initial_state: State[StateType],
- process_result: Callable[[StreamResultType, State[StateType]], tuple[StreamResultType, State[StateType]]],
- callback: Callable[[StreamResultType | None, State[StateType], Exception | None], Coroutine[None, None, None]],
Container for an async streaming result. This allows you to: 1. Iterate over the result as it comes in 2. Await the final result/state at the end
If you’re familiar with generators/iterators in python, this is effectively an iterator that caches the final result after calling it. This is meant to be used exclusively with the streaming action calls in Application. Note that you will never instantiate this class directly, but you will use it in the API when it is returned by
astream_result
. For reference, here’s how you would use it:action_we_just_ran, streaming_result_container = await application.stream_result(...) print(f"getting streaming results for action={action_we_just_ran.name}") async for result_component in streaming_result_container: print(result_component['response']) # this assumes you have a response key in your result final_result, final_state = await streaming_result_container.get()
- static pass_through(
- results: StreamResultType,
- final_state: State[StateType],
Creates a streaming result container that just passes through the given results. This is not a public facing API.
- class burr.core.action.streaming_action(reads: List[str], writes: List[str])¶
- static pydantic(
- reads: List[str],
- writes: List[str],
- state_input_type: Type[BaseModel],
- state_output_type: Type[BaseModel],
- stream_type: Type[BaseModel] | Type[dict],
Creates a streaming action that uses pydantic models.
- Parameters:
reads – The fields this consumes from the state.
writes – The fields this writes to the state.
stream_type – The pydantic model or dictionary type that is used to represent the partial results. Use a dict if you want this untyped.
state_input_type – The pydantic model type that is used to represent the input state.
state_output_type – The pydantic model type that is used to represent the output state.
- Returns:
The same function, decorated function.
- class burr.core.action.StreamingAction¶
Base class for Streaming action. These are “multi-step”, meaning that they run in multiple passes (run -> update)
- run(
- state: State[StateType],
- **run_kwargs,
Runs the streaming action through to completion.
- abstract stream_run(
- state: State[StateType],
- **run_kwargs,
Streaming action
stream_run
is different than standard action run. It: 1. streams in an intermediate result (the dict output) 2. yields the final result at the endNote that the user, in this case, is responsible for joining the result.
For instance, you could have:
def stream_run(state: State) -> Generator[dict, None, dict]: buffer = [] # you might want to be more efficient than simple strcat for token in query(state['prompt']): yield {'response' : token} buffer.append(token) yield {'response' : "".join(buffer)}
This would utilize a simple string buffer (implemented by a list) to store the results and then join them at the end. We return the final result.
- Parameters:
state – State to run the action on
run_kwargs – parameters passed to the run function – these are specified by inputs
- Returns:
A generator that streams in a result and returns the final result