|
from typing import List, Optional |
|
|
|
from pmcp.agents.agent_base import AgentBlueprint |
|
from langchain_core.tools import BaseTool |
|
from langchain_core.messages import AIMessage |
|
from langchain_openai import ChatOpenAI |
|
from langgraph.types import Command, interrupt |
|
from langchain_core.messages.utils import filter_messages |
|
|
|
from pmcp.models.state import PlanningState |
|
|
|
SYSTEM_PROMPT = """ |
|
You are a Human Reviewer Agent responsible for confirming the execution of tasks planned by the Planner Agent. Your role is to: |
|
- Ask the user for confirmation before an tool calling is performed. |
|
|
|
You are provided with the tool call details and the conversation history. |
|
""" |
|
|
|
|
|
class HumanInterruptNode: |
|
def __init__(self, llm: ChatOpenAI, tools: Optional[List[BaseTool]] = None): |
|
self.agent = AgentBlueprint( |
|
agent_name="HUMAN_REVIEWER_AGENT", |
|
description="The agent asks for human confirmation", |
|
tools=tools, |
|
system_prompt=SYSTEM_PROMPT.strip(), |
|
llm=llm, |
|
) |
|
|
|
def call_human_interrupt_agent(self, state: PlanningState): |
|
last_message = filter_messages(state.messages, include_types=[AIMessage])[-1] |
|
|
|
|
|
try: |
|
tool_call = last_message.tool_calls[-1] |
|
except Exception: |
|
last_message = filter_messages(state.messages, include_types=[AIMessage])[ |
|
-2 |
|
] |
|
tool_call = last_message.tool_calls[-1] |
|
|
|
if tool_call.get("name", "").startswith("get_"): |
|
return Command(goto="tool") |
|
|
|
response = self.agent.call_agent( |
|
messages=[ |
|
AIMessage(content=f"Tool Calling details: {str(tool_call)}"), |
|
] |
|
+ state.messages, |
|
) |
|
human_review = interrupt(response.content) |
|
|
|
confirm_action = human_review.confirm_action |
|
changes_description = human_review.changes_description |
|
|
|
if confirm_action: |
|
return Command(goto="tool") |
|
|
|
else: |
|
tool_message = { |
|
"role": "tool", |
|
"content": changes_description, |
|
"name": tool_call["name"], |
|
"tool_call_id": tool_call["id"], |
|
} |
|
return Command(goto="PLANNER_AGENT", update={"messages": [tool_message]}) |
|
|