Autograms Decorators
@autograms_function()
The @autograms_function()
decorator is a core feature of the Autograms framework, designed to enable dynamic control flow in conversational agents. It transforms standard Python functions into resumable, stateful workflows that can pause, serialize, and resume seamlessly. This allows chatbots or other interactive agents to act as one continuously running program that can be paused and saved at any time while waiting for input.
Key Features
-
Pause and Resume Execution:
Functions decorated with@autograms_function()
can pause at any point using special nodes (e.g.,reply
,reply_instruction
). These pauses return temporary responses to the user, while the function's state is saved and can be resumed from the exact point it left off. -
Memory management:
The function’s local variables, call stack, and conversation history are managed through an internal memory object, enabling serialization and reloading across different sessions. -
Conversation Scopes:
Manage how conversation history is retained using flexible scope options (global
,normal
,local
). -
Dynamic Control Flow:
The decorator supports advanced control mechanisms like GOTO and RETURNTO, allowing the program to jump to specific points in the function based on predefinedADDRESS
labels in functions decorated by@autograms_node
.
Parameters
- conv_scope (str, optional):
Defines the conversation scope. Defaults to"global"
. "global"
: Turns persist and are accessible across all nested calls."normal"
: Turns are accessible within the current function but do not persist after returning."local"
: Turns are isolated to the current function call.
Example usage
from autograms.nodes import reply, reply_instruction
from autograms.functional import yes_or_no
from autograms import autograms_function
#this decorator allows the function to have special behavior such as temporarily returning replies
@autograms_function()
def chatbot():
#model goes first here, we have a fixed introductory message. Pauses program and returns a reply
reply("Would you like me to tell you more about the latest advances in AI?", ADDRESS="ask_question")
#program will continue from this point after first user reply
#The agent decides whether it thinks the user wants to talk about AI based on their response
user_wants_ai = yes_or_no("does the user want to talk about AI?")
if user_wants_ai:
#pause and save program and return a reply based on instruction below
reply_instruction(
"Tell the user about the latest advances in AI. Mention that "
"a new framework called AutoGRAMS was recently released that allows greater control over AI agents.",
ADDRESS="tell_about_ai"
)
#continue program here after user response
else:
#pause and save program and return a reply based on instruction below
reply_instruction(
"Confirm with the user what they would prefer to talk about.",
ADDRESS="ask_preference"
)
#continue program here after user response
#infinite while loop continues conversation as long as user keeps responding
while True:
#pause and save program and output reply based on instruction below
reply_instruction("Respond to the user.", ADDRESS="continue_conversation")
#continue program here after user response
Restrictions
While @autograms_function
supports various control flow constructs, it may not handle resumption within certain node types (e.g., try
-except
, finally
). Ensure that ADDRESS
labels and pauses occur within supported contexts like loops and conditionals.
@autograms_external()
@autograms_external()
is meant to allow for functions that interact with user specific memory of the program to be called from outside of the normal conversation chain. The are mainly used to interact with user specific global variables
example use
@autograms_external()
def update_user_settings(user_command):
thought(f" The user made this request {user_command}. Should we change the chat_style setting? it is currently set to {user_globals['chat_style']}, and the options are {','.join(chat_styles)}")
idx =multiple_choice("what should the chat style be set to?",chat_styles)
user_globals['chat_style'] = chat_styles[idx]
And then in the Autogram object wrapping the module, you can do
autogram.apply(memory_object = memory_object,function=update_user_settings,user_command=user_command)
@autograms_external functions do not permanently modify the stack in the memory_object, are mainly used to change the UserGlobals object for user specific global variables defined in the module if there is one.
@autograms_node
Decorator for defining addressable nodes in Autograms. These nodes can serve as targets for GOTO
and RETURNTO
statements, enabling dynamic control flow within a function. They can also be used for logging and visualization purposes for showing graphs of the program, even if used without GOTO
or RETURNTO
.
Behavior
- Allows the function to be a target for
GOTO
andRETURNTO
statements. - When an
ADDRESS
is provided, the function call is logged and can be revisited.
Example usage
The following uses an autograms node combined with GOTO to design a chatbot that always replies with the next number of the Fibonacci sequence
from autograms import autograms_node,autograms_function
from autograms.functional import GOTO, reply
@autograms_node
def reply_value(value,ADDRESS=None):
#pauses program to reply
reply(f"value is now {value}")
@autograms_function():
def fibonacci():
x=1
reply_value(x)
x_last=x
reply_value(x+x_last,ADDRESS="output_x")
x_last=x
x = x+x_last
#facilitates loop by going to previous line with `reply_value(x+x_last,ADDRESS="output_x")`
GOTO(destination="output_x")