- fixes for multi-goal:post first real goal goal switch: duplicate listagents behavior from the toolplanner

- adding ecommerce initial guidance
- fixed new-goal guidance prompts for multi-goal mode
- (minor) fixed abug in money movement so it won't connect to temporal cloud if it's not doing a real workflow
- (minor) fixed abug in loan application so it won't connect to temporal cloud if it's not doing a real workflow
- some todo notes cleanup
This commit is contained in:
Joshua Smith
2025-04-18 17:08:44 -04:00
parent 32e856e494
commit d48dafcaa5
7 changed files with 42 additions and 28 deletions

View File

@@ -187,7 +187,7 @@ def generate_pick_new_goal_guidance()-> str:
str: A prompt string prompting the LLM to when to go to pick-new-goal str: A prompt string prompting the LLM to when to go to pick-new-goal
""" """
if is_multi_goal_mode(): if is_multi_goal_mode():
return 'Next should only be "pick-new-goal" if all tools have been run for the current goal (use the system prompt to figure that out) or the user explicitly requested to pick a new goal. If next is "pick-new-goal" the tool should always be "ListAgents"' return 'Next should only be "pick-new-goal" if all tools have been run for the current goal (use the system prompt to figure that out) and the last successful tool was not ListAgents, or the user explicitly requested to pick a new goal.'
else: else:
return 'Next should never be "pick-new-goal".' return 'Next should never be "pick-new-goal".'

View File

@@ -210,6 +210,9 @@ FIN_START_REAL_WORKFLOW=FALSE #set this to true to start a real workflow
#### Goals: HR/PTO #### Goals: HR/PTO
Make sure you have the mock users you want in (such as yourself) in [the PTO mock data file](./tools/data/employee_pto_data.json). Make sure you have the mock users you want in (such as yourself) in [the PTO mock data file](./tools/data/employee_pto_data.json).
#### Goals: Ecommerce
Make sure you have the mock orders you want in (such as those with real tracking numbers) in [the mock orders file](./tools/data/customer_order_data.json).
## Customizing the Agent Further ## Customizing the Agent Further
- `tool_registry.py` contains the mapping of tool names to tool definitions (so the AI understands how to use them) - `tool_registry.py` contains the mapping of tool names to tool definitions (so the AI understands how to use them)

View File

@@ -12,9 +12,9 @@
[ ] for demo simulate failure - add utilities/simulated failures from pipeline demo <br /> [ ] for demo simulate failure - add utilities/simulated failures from pipeline demo <br />
[ ] ecommerce goals <br /> [x] ecommerce goals <br />
- [ ] add to docs <br /> - [x] add to docs <br />
- [ ] decide about api key names with Laine <br /> - [x] decide about api key names with Laine <br />
[ ] LLM failure->autoswitch: <br /> [ ] LLM failure->autoswitch: <br />
- detect failure in the activity using failurecount <br /> - detect failure in the activity using failurecount <br />

View File

@@ -77,8 +77,6 @@ async def move_money(args: dict) -> dict:
# Async function to start workflow # Async function to start workflow
async def start_workflow(amount_cents: int, from_account_name: str, to_account_name: str)-> str: async def start_workflow(amount_cents: int, from_account_name: str, to_account_name: str)-> str:
# Connect to Temporal
client = await get_temporal_client()
start_real_workflow = os.getenv("FIN_START_REAL_WORKFLOW") start_real_workflow = os.getenv("FIN_START_REAL_WORKFLOW")
if start_real_workflow is not None and start_real_workflow.lower() == "false": if start_real_workflow is not None and start_real_workflow.lower() == "false":
START_REAL_WORKFLOW = False START_REAL_WORKFLOW = False
@@ -86,6 +84,8 @@ async def start_workflow(amount_cents: int, from_account_name: str, to_account_n
START_REAL_WORKFLOW = True START_REAL_WORKFLOW = True
if START_REAL_WORKFLOW: if START_REAL_WORKFLOW:
# Connect to Temporal
client = await get_temporal_client()
# Create the parameter object # Create the parameter object
params = MoneyMovementWorkflowParameterObj( params = MoneyMovementWorkflowParameterObj(
amount=amount_cents, amount=amount_cents,

View File

@@ -46,14 +46,14 @@ async def submit_loan_application(args: dict) -> dict:
# Async function to start workflow # Async function to start workflow
async def start_workflow(amount: str, account_name: str, )-> dict: async def start_workflow(amount: str, account_name: str, )-> dict:
# Connect to Temporal
client = await get_temporal_client()
start_real_workflow = os.getenv("FIN_START_REAL_WORKFLOW") start_real_workflow = os.getenv("FIN_START_REAL_WORKFLOW")
if start_real_workflow is not None and start_real_workflow.lower() == "false": if start_real_workflow is not None and start_real_workflow.lower() == "false":
START_REAL_WORKFLOW = False START_REAL_WORKFLOW = False
return {'loan_application_status': "applied", 'application_details': "loan application is submitted and initial validation is complete",'transaction_id': "APPLICATION"+account_name, 'advisement': "You'll receive a confirmation for final approval in three business days", } return {'loan_application_status': "applied", 'application_details': "loan application is submitted and initial validation is complete",'transaction_id': "APPLICATION"+account_name, 'advisement': "You'll receive a confirmation for final approval in three business days", }
else: else:
START_REAL_WORKFLOW = True START_REAL_WORKFLOW = True
# Connect to Temporal
client = await get_temporal_client()
# Define the workflow ID and task queue # Define the workflow ID and task queue
workflow_id = "LOAN_APPLICATION-"+account_name+"-"+date.today().strftime('%Y-%m-%d') workflow_id = "LOAN_APPLICATION-"+account_name+"-"+date.today().strftime('%Y-%m-%d')

View File

@@ -345,7 +345,7 @@ goal_fin_move_money = AgentGoal(
) )
# this starts a loan approval process # this starts a loan approval process
# it also uses a separate workflow/tool, see ./setup.md for details #todo # it also uses a separate workflow/tool, see ./setup.md for details
goal_fin_loan_application = AgentGoal( goal_fin_loan_application = AgentGoal(
id = "goal_fin_loan_application", id = "goal_fin_loan_application",
category_tag="fin", category_tag="fin",
@@ -353,7 +353,7 @@ goal_fin_loan_application = AgentGoal(
agent_friendly_description="Initiate loan application.", agent_friendly_description="Initiate loan application.",
tools=[ tools=[
tool_registry.financial_check_account_is_valid, tool_registry.financial_check_account_is_valid,
tool_registry.financial_submit_loan_approval, #todo tool_registry.financial_submit_loan_approval,
], ],
description="The user wants to apply for a loan at the financial institution. To assist with that goal, help the user gather args for these tools in order: " description="The user wants to apply for a loan at the financial institution. To assist with that goal, help the user gather args for these tools in order: "
"1. FinCheckAccountIsValid: validate the user's account is valid" "1. FinCheckAccountIsValid: validate the user's account is valid"
@@ -375,7 +375,6 @@ goal_fin_loan_application = AgentGoal(
), ),
) )
# ----- E-Commerce Goals --- # ----- E-Commerce Goals ---
#todo: add goal to list all orders for last X amount of time?
# this tool checks account balances, and uses ./data/customer_account_data.json as dummy data # this tool checks account balances, and uses ./data/customer_account_data.json as dummy data
goal_ecomm_order_status = AgentGoal( goal_ecomm_order_status = AgentGoal(
id = "goal_ecomm_order_status", id = "goal_ecomm_order_status",

View File

@@ -172,7 +172,9 @@ class AgentGoalWorkflow:
# else if the next step is to pick a new goal, set the goal and tool to do it # else if the next step is to pick a new goal, set the goal and tool to do it
elif next_step == "pick-new-goal": elif next_step == "pick-new-goal":
workflow.logger.info("All steps completed. Resetting goal.") if self.goal.id != "goal_choose_agent_type":
self.add_message("agent", tool_data)
workflow.logger.info("All tools completed and new Agent Goal recommended. Resetting goal.")
self.change_goal("goal_choose_agent_type") self.change_goal("goal_choose_agent_type")
next_step = tool_data["next"] = "confirm" next_step = tool_data["next"] = "confirm"
current_tool = tool_data["tool"] = "ListAgents" current_tool = tool_data["tool"] = "ListAgents"
@@ -183,10 +185,20 @@ class AgentGoalWorkflow:
# if we have all needed arguments (handled above) and not holding for a debugging confirm, proceed: # if we have all needed arguments (handled above) and not holding for a debugging confirm, proceed:
else: else:
self.confirmed = True self.confirmed = True
#self.print_useful_workflow_vars("before adding agent message<-- tool data") continue
# maybe want to do this sometimes? for now it loops self.add_message("agent", tool_data) else:
self.print_useful_workflow_vars("after pick-new-goal") if not current_tool == "ListAgents":
continue # try with this out current_tool = tool_data["tool"] = "ListAgents"
waiting_for_confirm = True
self.tool_data = tool_data
next_step = tool_data["next"] = "confirm"
if self.show_tool_args_confirmation:
self.confirmed = False
# if we have all needed arguments (handled above) and not holding for a debugging confirm, proceed:
else:
self.confirmed = True
# else if the next step is to be done with the conversation such as if the user requests it via asking to "end conversation" # else if the next step is to be done with the conversation such as if the user requests it via asking to "end conversation"
elif next_step == "done": elif next_step == "done":
@@ -357,14 +369,12 @@ class AgentGoalWorkflow:
self.prompt_queue self.prompt_queue
) )
#set new goal if we should # set new goal if we should
if len(self.tool_results) > 0: if len(self.tool_results) > 0:
if "ChangeGoal" in self.tool_results[-1].values() and "new_goal" in self.tool_results[-1].keys(): if "ChangeGoal" in self.tool_results[-1].values() and "new_goal" in self.tool_results[-1].keys():
new_goal = self.tool_results[-1].get("new_goal") new_goal = self.tool_results[-1].get("new_goal")
workflow.logger.info(f"Booya new goal!: {new_goal}")
self.change_goal(new_goal) self.change_goal(new_goal)
elif "ListAgents" in self.tool_results[-1].values() and self.goal.id != "goal_choose_agent_type": elif "ListAgents" in self.tool_results[-1].values() and self.goal.id != "goal_choose_agent_type":
workflow.logger.info("setting goal to goal_choose_agent_type")
self.change_goal("goal_choose_agent_type") self.change_goal("goal_choose_agent_type")
return waiting_for_confirm return waiting_for_confirm
@@ -372,6 +382,8 @@ class AgentGoalWorkflow:
# also don't forget you can look at the workflow itself and do queries if you want # also don't forget you can look at the workflow itself and do queries if you want
def print_useful_workflow_vars(self, status_or_step:str) -> None: def print_useful_workflow_vars(self, status_or_step:str) -> None:
print(f"***{status_or_step}:***") print(f"***{status_or_step}:***")
if self.goal:
print(f"current goal: {self.goal.id}")
if self.tool_data: if self.tool_data:
print(f"force confirm? {self.tool_data['force_confirm']}") print(f"force confirm? {self.tool_data['force_confirm']}")
print(f"next step: {self.tool_data.get('next')}") print(f"next step: {self.tool_data.get('next')}")