mirror of
https://github.com/temporal-community/temporal-ai-agent.git
synced 2026-03-15 14:08:08 +01:00
Merge branch 'development' of https://github.com/joshmsmith/temporal-ai-agent into development
This commit is contained in:
@@ -194,7 +194,6 @@ async def end_chat():
|
|||||||
|
|
||||||
@app.post("/start-workflow")
|
@app.post("/start-workflow")
|
||||||
async def start_workflow():
|
async def start_workflow():
|
||||||
# Get the initial goal as set in shared/config or env or just...always should be "pick a goal?"
|
|
||||||
initial_agent_goal = get_initial_agent_goal()
|
initial_agent_goal = get_initial_agent_goal()
|
||||||
|
|
||||||
# Create combined input
|
# Create combined input
|
||||||
|
|||||||
@@ -81,9 +81,8 @@ def generate_genai_prompt(
|
|||||||
"1) If any required argument is missing, set next='question' and ask the user.\n"
|
"1) If any required argument is missing, set next='question' and ask the user.\n"
|
||||||
"2) If all required arguments are known, set next='confirm' and specify the tool.\n"
|
"2) If all required arguments are known, set next='confirm' and specify the tool.\n"
|
||||||
" The user will confirm before the tool is run.\n"
|
" The user will confirm before the tool is run.\n"
|
||||||
"3) If no more tools are needed (user_confirmed_tool_run has been run for all), set next='done' and tool=null.\n"
|
"3) If no more tools are needed (user_confirmed_tool_run has been run for all), set next='confirm' and tool='ListAgents'.\n"
|
||||||
"4) response should be short and user-friendly.\n"
|
"4) response should be short and user-friendly.\n"
|
||||||
"5) Don't set next='done' until the final tool has returned user_confirmed_tool_run.\n"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
# Validation Task (If raw_json is provided)
|
# Validation Task (If raw_json is provided)
|
||||||
@@ -126,9 +125,7 @@ def generate_tool_completion_prompt(current_tool: str, dynamic_result: dict) ->
|
|||||||
"You will need to use the tool_results to auto-fill arguments for subsequent tools and also to figure out if all tools have been run."
|
"You will need to use the tool_results to auto-fill arguments for subsequent tools and also to figure out if all tools have been run."
|
||||||
'{"next": "<question|confirm|done>", "tool": "<tool_name or null>", "args": {"<arg1>": "<value1 or null>", "<arg2>": "<value2 or null>}, "response": "<plain text (can include \\n line breaks)>"}'
|
'{"next": "<question|confirm|done>", "tool": "<tool_name or null>", "args": {"<arg1>": "<value1 or null>", "<arg2>": "<value2 or null>}, "response": "<plain text (can include \\n line breaks)>"}'
|
||||||
"ONLY return those json keys (next, tool, args, response), nothing else."
|
"ONLY return those json keys (next, tool, args, response), nothing else."
|
||||||
'Next should only be "done" if all tools have been run (use the system prompt to figure that out).'
|
'Next should be "question".'
|
||||||
'Next should be "question" if the tool is not the last one in the sequence.'
|
|
||||||
'Next should NOT be "confirm" at this point.'
|
|
||||||
)
|
)
|
||||||
|
|
||||||
def generate_missing_args_prompt(current_tool: str, tool_data: dict, missing_args: list[str]) -> str:
|
def generate_missing_args_prompt(current_tool: str, tool_data: dict, missing_args: list[str]) -> str:
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ from .search_trains import search_trains
|
|||||||
from .search_trains import book_trains
|
from .search_trains import book_trains
|
||||||
from .create_invoice import create_invoice
|
from .create_invoice import create_invoice
|
||||||
from .find_events import find_events
|
from .find_events import find_events
|
||||||
from .choose_agent import choose_agent
|
from .list_agents import list_agents
|
||||||
from .change_goal import change_goal
|
from .change_goal import change_goal
|
||||||
from .transfer_control import transfer_control
|
from .transfer_control import transfer_control
|
||||||
|
|
||||||
@@ -22,8 +22,8 @@ def get_handler(tool_name: str):
|
|||||||
return create_invoice
|
return create_invoice
|
||||||
if tool_name == "FindEvents":
|
if tool_name == "FindEvents":
|
||||||
return find_events
|
return find_events
|
||||||
if tool_name == "ChooseAgent":
|
if tool_name == "ListAgents":
|
||||||
return choose_agent
|
return list_agents
|
||||||
if tool_name == "ChangeGoal":
|
if tool_name == "ChangeGoal":
|
||||||
return change_goal
|
return change_goal
|
||||||
if tool_name == "TransferControl":
|
if tool_name == "TransferControl":
|
||||||
|
|||||||
@@ -13,8 +13,7 @@ import shared.config
|
|||||||
def change_goal(args: dict) -> dict:
|
def change_goal(args: dict) -> dict:
|
||||||
|
|
||||||
new_goal = args.get("goalID")
|
new_goal = args.get("goalID")
|
||||||
shared.config.AGENT_GOAL = new_goal
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
"new_goal": shared.config.AGENT_GOAL,
|
"new_goal": new_goal,
|
||||||
}
|
}
|
||||||
@@ -7,39 +7,32 @@ from tools.tool_registry import (
|
|||||||
create_invoice_tool,
|
create_invoice_tool,
|
||||||
find_events_tool,
|
find_events_tool,
|
||||||
change_goal_tool,
|
change_goal_tool,
|
||||||
choose_agent_tool,
|
list_agents_tool
|
||||||
transfer_control_tool
|
|
||||||
)
|
)
|
||||||
|
|
||||||
starter_prompt_generic = "Welcome me, give me a description of what you can do, then ask me for the details you need to do your job"
|
starter_prompt_generic = "Welcome me, give me a description of what you can do, then ask me for the details you need to do your job"
|
||||||
|
|
||||||
goal_choose_agent_type = AgentGoal(
|
goal_choose_agent_type = AgentGoal(
|
||||||
tools=[
|
tools=[
|
||||||
choose_agent_tool,
|
list_agents_tool,
|
||||||
change_goal_tool,
|
change_goal_tool
|
||||||
transfer_control_tool
|
|
||||||
],
|
],
|
||||||
description="The user wants to choose which type of agent they will interact with. "
|
description="The user wants to choose which type of agent they will interact with. "
|
||||||
"Help the user gather args for these tools, in order: "
|
"Help the user gather args for these tools, in order: "
|
||||||
"1. ChooseAgent: Choose which agent to interact with "
|
"1. ListAgents: List agents available to interact with "
|
||||||
"2. ChangeGoal: Change goal of agent "
|
"2. ChangeGoal: Change goal of agent "
|
||||||
"3. TransferControl: Transfer control to new agent "
|
|
||||||
"After these tools are complete, change your goal to the new goal as chosen by the user. ",
|
"After these tools are complete, change your goal to the new goal as chosen by the user. ",
|
||||||
starter_prompt=starter_prompt_generic,
|
starter_prompt=starter_prompt_generic,
|
||||||
example_conversation_history="\n ".join(
|
example_conversation_history="\n ".join(
|
||||||
[
|
[
|
||||||
"user: I'd like to choose an agent",
|
"user: I'd like to choose an agent",
|
||||||
"agent: Sure! Would you like me to list the available agents?",
|
"agent: Sure! Would you like me to list the available agents?",
|
||||||
"user_confirmed_tool_run: <user clicks confirm on ChooseAgent tool>",
|
"user_confirmed_tool_run: <user clicks confirm on ListAgents tool>",
|
||||||
"tool_result: { 'agent_name': 'Event Flight Finder', 'goal_id': 'goal_event_flight_invoice', 'agent_description': 'Helps users find interesting events and arrange travel to them' }",
|
"tool_result: { 'agent_name': 'Event Flight Finder', 'goal_id': 'goal_event_flight_invoice', 'agent_description': 'Helps users find interesting events and arrange travel to them' }",
|
||||||
"agent: The available agents are: 1. Event Flight Finder. Which agent would you like to speak to?",
|
"agent: The available agents are: 1. Event Flight Finder. Which agent would you like to speak to?",
|
||||||
"user: 1",
|
"user: 1",
|
||||||
"user_confirmed_tool_run: <user clicks confirm on ChangeGoal tool>",
|
"user_confirmed_tool_run: <user clicks confirm on ChangeGoal tool>",
|
||||||
# bot changes goal here and hopefully just...switches??
|
|
||||||
# could also end 1 workflow and start another with new goal
|
|
||||||
"tool_result: { 'new_goal': 'goal_event_flight_invoice' }",
|
"tool_result: { 'new_goal': 'goal_event_flight_invoice' }",
|
||||||
"agent: Would you like to transfer control to the new agent now?",
|
|
||||||
"user: yes",
|
|
||||||
]
|
]
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
import json
|
import json
|
||||||
|
|
||||||
def choose_agent(args: dict) -> dict:
|
def list_agents(args: dict) -> dict:
|
||||||
|
|
||||||
# file_path = Path(__file__).resolve().parent / "goal_regsitry.py"
|
# file_path = Path(__file__).resolve().parent / "goal_regsitry.py"
|
||||||
#if not file_path.exists():
|
#if not file_path.exists():
|
||||||
@@ -1,21 +1,7 @@
|
|||||||
from models.tool_definitions import ToolDefinition, ToolArgument
|
from models.tool_definitions import ToolDefinition, ToolArgument
|
||||||
|
|
||||||
#This also doesn't help...
|
list_agents_tool = ToolDefinition(
|
||||||
transfer_control_tool = ToolDefinition(
|
name="ListAgents",
|
||||||
name="TransferControl",
|
|
||||||
description="Do one extra input from user to apply the new goal to the workflow (Hacky, hopefully temp). ",
|
|
||||||
arguments=[
|
|
||||||
ToolArgument(
|
|
||||||
name="userConfirmation",
|
|
||||||
type="string",
|
|
||||||
description="dummy variable to make thing work",
|
|
||||||
),
|
|
||||||
],
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
choose_agent_tool = ToolDefinition(
|
|
||||||
name="ChooseAgent",
|
|
||||||
description="List available agents to interact with, pulled from goal_registry. ",
|
description="List available agents to interact with, pulled from goal_registry. ",
|
||||||
arguments=[
|
arguments=[
|
||||||
ToolArgument(
|
ToolArgument(
|
||||||
|
|||||||
@@ -12,9 +12,6 @@ from workflows.workflow_helpers import LLM_ACTIVITY_START_TO_CLOSE_TIMEOUT, \
|
|||||||
LLM_ACTIVITY_SCHEDULE_TO_CLOSE_TIMEOUT
|
LLM_ACTIVITY_SCHEDULE_TO_CLOSE_TIMEOUT
|
||||||
from workflows import workflow_helpers as helpers
|
from workflows import workflow_helpers as helpers
|
||||||
|
|
||||||
|
|
||||||
#importlib.reload(my_module)
|
|
||||||
|
|
||||||
with workflow.unsafe.imports_passed_through():
|
with workflow.unsafe.imports_passed_through():
|
||||||
from activities.tool_activities import ToolActivities
|
from activities.tool_activities import ToolActivities
|
||||||
from prompts.agent_prompt_generators import (
|
from prompts.agent_prompt_generators import (
|
||||||
@@ -24,9 +21,6 @@ with workflow.unsafe.imports_passed_through():
|
|||||||
CombinedInput,
|
CombinedInput,
|
||||||
ToolPromptInput,
|
ToolPromptInput,
|
||||||
)
|
)
|
||||||
import shared.config
|
|
||||||
importlib.reload(shared.config)
|
|
||||||
#from shared.config import AGENT_GOAL
|
|
||||||
from tools.goal_registry import goal_match_train_invoice, goal_event_flight_invoice, goal_choose_agent_type
|
from tools.goal_registry import goal_match_train_invoice, goal_event_flight_invoice, goal_choose_agent_type
|
||||||
|
|
||||||
# Constants
|
# Constants
|
||||||
@@ -50,7 +44,6 @@ class AgentGoalWorkflow:
|
|||||||
self.tool_data: Optional[ToolData] = None
|
self.tool_data: Optional[ToolData] = None
|
||||||
self.confirm: bool = False
|
self.confirm: bool = False
|
||||||
self.tool_results: List[Dict[str, Any]] = []
|
self.tool_results: List[Dict[str, Any]] = []
|
||||||
#set initial goal of "pick an agent" here??
|
|
||||||
self.goal: AgentGoal = {"tools": []}
|
self.goal: AgentGoal = {"tools": []}
|
||||||
|
|
||||||
# see ../api/main.py#temporal_client.start_workflow() for how the input parameters are set
|
# see ../api/main.py#temporal_client.start_workflow() for how the input parameters are set
|
||||||
@@ -111,16 +104,8 @@ class AgentGoalWorkflow:
|
|||||||
if len(self.tool_results) > 0 and "new_goal" in self.tool_results[-1].keys() and "ChangeGoal" in self.tool_results[-1].values():
|
if len(self.tool_results) > 0 and "new_goal" in self.tool_results[-1].keys() and "ChangeGoal" in self.tool_results[-1].values():
|
||||||
|
|
||||||
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}")
|
workflow.logger.warning(f"Booya new goal!: {new_goal}")
|
||||||
goals = {
|
self.change_goal(new_goal)
|
||||||
"goal_match_train_invoice": goal_match_train_invoice,
|
|
||||||
"goal_event_flight_invoice": goal_event_flight_invoice,
|
|
||||||
"goal_choose_agent_type": goal_choose_agent_type,
|
|
||||||
}
|
|
||||||
|
|
||||||
if new_goal is not None:
|
|
||||||
self.goal = goals.get(new_goal)
|
|
||||||
#todo reset goal or tools if this doesn't work or whatever
|
|
||||||
continue
|
continue
|
||||||
|
|
||||||
# push messages to UI if there are any
|
# push messages to UI if there are any
|
||||||
@@ -264,3 +249,15 @@ class AgentGoalWorkflow:
|
|||||||
self.conversation_history["messages"].append(
|
self.conversation_history["messages"].append(
|
||||||
{"actor": actor, "response": response}
|
{"actor": actor, "response": response}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
def change_goal(self, goal: str) -> None:
|
||||||
|
goals = {
|
||||||
|
"goal_match_train_invoice": goal_match_train_invoice,
|
||||||
|
"goal_event_flight_invoice": goal_event_flight_invoice,
|
||||||
|
"goal_choose_agent_type": goal_choose_agent_type,
|
||||||
|
}
|
||||||
|
|
||||||
|
if goal is not None:
|
||||||
|
self.goal = goals.get(goal)
|
||||||
|
workflow.logger.warning("Changed goal to " + goal)
|
||||||
|
#todo reset goal or tools if this doesn't work or whatever
|
||||||
|
|||||||
Reference in New Issue
Block a user