mirror of
https://github.com/temporal-community/temporal-ai-agent.git
synced 2026-03-15 14:08:08 +01:00
Add a bunch of logging and comments re: what's happenin'
This commit is contained in:
@@ -1,5 +1,6 @@
|
|||||||
from collections import deque
|
from collections import deque
|
||||||
from datetime import timedelta
|
from datetime import timedelta
|
||||||
|
import os
|
||||||
from typing import Dict, Any, Union, List, Optional, Deque, TypedDict
|
from typing import Dict, Any, Union, List, Optional, Deque, TypedDict
|
||||||
|
|
||||||
from temporalio.common import RetryPolicy
|
from temporalio.common import RetryPolicy
|
||||||
@@ -25,6 +26,8 @@ with workflow.unsafe.imports_passed_through():
|
|||||||
# Constants
|
# Constants
|
||||||
MAX_TURNS_BEFORE_CONTINUE = 250
|
MAX_TURNS_BEFORE_CONTINUE = 250
|
||||||
|
|
||||||
|
SHOW_CONFIRM = os.getenv("SHOW_CONFIRM", True)
|
||||||
|
|
||||||
class ToolData(TypedDict, total=False):
|
class ToolData(TypedDict, total=False):
|
||||||
next: NextStep
|
next: NextStep
|
||||||
tool: str
|
tool: str
|
||||||
@@ -77,12 +80,13 @@ class AgentGoalWorkflow:
|
|||||||
|
|
||||||
# handle chat-end signal
|
# handle chat-end signal
|
||||||
if self.chat_ended:
|
if self.chat_ended:
|
||||||
|
workflow.logger.warning(f"workflow step: chat-end signal received, ending")
|
||||||
workflow.logger.info("Chat ended.")
|
workflow.logger.info("Chat ended.")
|
||||||
|
|
||||||
return f"{self.conversation_history}"
|
return f"{self.conversation_history}"
|
||||||
|
|
||||||
# execute tool
|
# user has confirmed, now actually execute the tool
|
||||||
if self.confirm and waiting_for_confirm and current_tool and self.tool_data:
|
if self.confirm and waiting_for_confirm and current_tool and self.tool_data:
|
||||||
|
workflow.logger.warning(f"workflow step: user has confirmed, executing the tool {current_tool}")
|
||||||
self.confirm = False
|
self.confirm = False
|
||||||
waiting_for_confirm = False
|
waiting_for_confirm = False
|
||||||
|
|
||||||
@@ -112,10 +116,11 @@ class AgentGoalWorkflow:
|
|||||||
self.change_goal("goal_choose_agent_type")
|
self.change_goal("goal_choose_agent_type")
|
||||||
continue
|
continue
|
||||||
|
|
||||||
# push messages to UI if there are any
|
# if we've received messages to be processed on the prompt queue...
|
||||||
if self.prompt_queue:
|
if self.prompt_queue:
|
||||||
prompt = self.prompt_queue.popleft()
|
prompt = self.prompt_queue.popleft()
|
||||||
if not prompt.startswith("###"):
|
workflow.logger.warning(f"workflow step: processing message on the prompt queue, message is {prompt}")
|
||||||
|
if not prompt.startswith("###"): #if the message isn't from the LLM but is instead from the user
|
||||||
self.add_message("user", prompt)
|
self.add_message("user", prompt)
|
||||||
|
|
||||||
# Validate the prompt before proceeding
|
# Validate the prompt before proceeding
|
||||||
@@ -134,27 +139,17 @@ class AgentGoalWorkflow:
|
|||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
|
||||||
#If validation fails, provide that feedback to the user - i.e., "your words make no sense, human"
|
#If validation fails, provide that feedback to the user - i.e., "your words make no sense, puny human" end this iteration of processing
|
||||||
if not validation_result.validationResult:
|
if not validation_result.validationResult:
|
||||||
workflow.logger.warning(
|
workflow.logger.warning(f"Prompt validation failed: {validation_result.validationFailedReason}")
|
||||||
f"Prompt validation failed: {validation_result.validationFailedReason}"
|
self.add_message("agent", validation_result.validationFailedReason)
|
||||||
)
|
|
||||||
self.add_message(
|
|
||||||
"agent", validation_result.validationFailedReason
|
|
||||||
)
|
|
||||||
continue
|
continue
|
||||||
|
|
||||||
# Proceed with generating the context and prompt
|
# If valid, proceed with generating the context and prompt
|
||||||
context_instructions = generate_genai_prompt(
|
context_instructions = generate_genai_prompt(self.goal, self.conversation_history, self.tool_data)
|
||||||
self.goal, self.conversation_history, self.tool_data
|
prompt_input = ToolPromptInput(prompt=prompt, context_instructions=context_instructions)
|
||||||
)
|
|
||||||
|
|
||||||
prompt_input = ToolPromptInput(
|
# connect to LLM and execute to get next steps
|
||||||
prompt=prompt,
|
|
||||||
context_instructions=context_instructions,
|
|
||||||
)
|
|
||||||
|
|
||||||
# connect to LLM and get it to create a prompt for the user about the tool
|
|
||||||
tool_data = await workflow.execute_activity(
|
tool_data = await workflow.execute_activity(
|
||||||
ToolActivities.agent_toolPlanner,
|
ToolActivities.agent_toolPlanner,
|
||||||
prompt_input,
|
prompt_input,
|
||||||
@@ -166,33 +161,34 @@ class AgentGoalWorkflow:
|
|||||||
)
|
)
|
||||||
self.tool_data = tool_data
|
self.tool_data = tool_data
|
||||||
|
|
||||||
# move forward in the tool chain
|
# process the tool as dictated by the prompt response - what to do next, and with which tool
|
||||||
next_step = tool_data.get("next")
|
next_step = tool_data.get("next")
|
||||||
current_tool = tool_data.get("tool")
|
current_tool = tool_data.get("tool")
|
||||||
if "next" in self.tool_data.keys():
|
|
||||||
workflow.logger.warning(f"ran the toolplanner, next step: {next_step}")
|
|
||||||
else:
|
|
||||||
workflow.logger.warning("ran the toolplanner, next step not set!")
|
|
||||||
|
|
||||||
|
#if the next step is to confirm...
|
||||||
if next_step == "confirm" and current_tool:
|
if next_step == "confirm" and current_tool:
|
||||||
workflow.logger.warning("next_step: confirm, ran the toolplanner, trying to confirm")
|
workflow.logger.warning(f"next_step: confirm, current tool is {current_tool}")
|
||||||
args = tool_data.get("args", {})
|
args = tool_data.get("args", {})
|
||||||
|
#if we're missing arguments, go back to the top of the loop
|
||||||
if await helpers.handle_missing_args(current_tool, args, tool_data, self.prompt_queue):
|
if await helpers.handle_missing_args(current_tool, args, tool_data, self.prompt_queue):
|
||||||
continue
|
continue
|
||||||
|
|
||||||
|
#...otherwise, set up the request for user confirmation
|
||||||
waiting_for_confirm = True
|
waiting_for_confirm = True
|
||||||
self.confirm = False
|
self.confirm = False
|
||||||
workflow.logger.info("Waiting for user confirm signal...")
|
workflow.logger.info("Waiting for user confirm signal...")
|
||||||
|
|
||||||
# todo probably here we can set the next step to be change-goal
|
# else if the next step is to pick a new goal...
|
||||||
elif next_step == "pick-new-goal":
|
elif next_step == "pick-new-goal":
|
||||||
workflow.logger.info("All steps completed. Resetting goal.")
|
workflow.logger.info("All steps completed. Resetting goal.")
|
||||||
workflow.logger.warning("next_step = pick-new-goal, setting goal to goal_choose_agent_type")
|
workflow.logger.warning("next_step = pick-new-goal, setting goal to goal_choose_agent_type")
|
||||||
self.change_goal("goal_choose_agent_type")
|
self.change_goal("goal_choose_agent_type")
|
||||||
|
|
||||||
|
# else if the next step is to be done - this should only happen if the user requests it via "end conversation"
|
||||||
elif next_step == "done":
|
elif next_step == "done":
|
||||||
workflow.logger.warning("next_step = done")
|
workflow.logger.warning("next_step = done")
|
||||||
self.add_message("agent", tool_data)
|
self.add_message("agent", tool_data)
|
||||||
|
# end the workflow
|
||||||
return str(self.conversation_history)
|
return str(self.conversation_history)
|
||||||
|
|
||||||
self.add_message("agent", tool_data)
|
self.add_message("agent", tool_data)
|
||||||
@@ -208,8 +204,9 @@ class AgentGoalWorkflow:
|
|||||||
@workflow.signal
|
@workflow.signal
|
||||||
async def user_prompt(self, prompt: str) -> None:
|
async def user_prompt(self, prompt: str) -> None:
|
||||||
"""Signal handler for receiving user prompts."""
|
"""Signal handler for receiving user prompts."""
|
||||||
|
workflow.logger.warning(f"signal received: user_prompt, prompt is {prompt}")
|
||||||
if self.chat_ended:
|
if self.chat_ended:
|
||||||
workflow.logger.warn(f"Message dropped due to chat closed: {prompt}")
|
workflow.logger.warning(f"Message dropped due to chat closed: {prompt}")
|
||||||
return
|
return
|
||||||
self.prompt_queue.append(prompt)
|
self.prompt_queue.append(prompt)
|
||||||
|
|
||||||
@@ -218,12 +215,14 @@ class AgentGoalWorkflow:
|
|||||||
async def confirm(self) -> None:
|
async def confirm(self) -> None:
|
||||||
"""Signal handler for user confirmation of tool execution."""
|
"""Signal handler for user confirmation of tool execution."""
|
||||||
workflow.logger.info("Received user confirmation")
|
workflow.logger.info("Received user confirmation")
|
||||||
|
workflow.logger.warning(f"signal recieved: confirm")
|
||||||
self.confirm = True
|
self.confirm = True
|
||||||
|
|
||||||
#Signal that comes from api/main.py via a post to /end-chat
|
#Signal that comes from api/main.py via a post to /end-chat
|
||||||
@workflow.signal
|
@workflow.signal
|
||||||
async def end_chat(self) -> None:
|
async def end_chat(self) -> None:
|
||||||
"""Signal handler for ending the chat session."""
|
"""Signal handler for ending the chat session."""
|
||||||
|
workflow.logger.warning("signal received: end_chat")
|
||||||
self.chat_ended = True
|
self.chat_ended = True
|
||||||
|
|
||||||
@workflow.query
|
@workflow.query
|
||||||
|
|||||||
Reference in New Issue
Block a user