-
Notifications
You must be signed in to change notification settings - Fork 46
Added the HIL Feature Using LangChains interrupt() command #130
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
1fe20d3
d417087
195334c
d151fe8
b278a37
21ae386
a492276
b040586
6bc44c3
c796f4a
e52fe0e
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -7,10 +7,30 @@ | |
|
||
logger = logging.getLogger(__name__) | ||
|
||
HIL_INTERRUPT_ACTIONS = ["web_search", "faq_handler", "onboarding", "github_toolkit"] | ||
|
||
|
||
async def react_supervisor_node(state: AgentState, llm) -> Dict[str, Any]: | ||
"""ReAct Supervisor: Think -> Act -> Observe""" | ||
logger.info(f"ReAct Supervisor thinking for session {state.session_id}") | ||
|
||
repo = state.context.get("repository") | ||
if not repo: | ||
waiting_for_user_input = True | ||
interrupt_details = { | ||
"prompt": "Before we proceed, could you please specify the project or repository you are working on?" | ||
} | ||
logger.info(f"Human-in-the-Loop interrupt: asking for repository context in session {state.session_id}") | ||
|
||
updated_context = { | ||
**state.context, | ||
"waiting_for_user_input": True, | ||
"interrupt_details": interrupt_details | ||
} | ||
return { | ||
"context": updated_context, | ||
"current_task": "waiting_for_user_input_repo" | ||
} | ||
# Get current context | ||
latest_message = _get_latest_message(state) | ||
conversation_history = _get_conversation_history(state) | ||
|
@@ -31,15 +51,42 @@ async def react_supervisor_node(state: AgentState, llm) -> Dict[str, Any]: | |
|
||
logger.info(f"ReAct Supervisor decision: {decision['action']}") | ||
|
||
# Update state with supervisor's thinking | ||
waiting_for_user_input = False | ||
interrupt_details = {} | ||
|
||
if decision["action"] in HIL_INTERRUPT_ACTIONS: | ||
# Here you can add logic to decide if user input is needed | ||
# For example, if decision thinking contains uncertainty or multiple options | ||
# For demo, we just always pause at these actions to ask the user | ||
waiting_for_user_input = True | ||
interrupt_details = { | ||
"prompt": f"The agent wants to execute the action: {decision['action']}. Please confirm or provide input." | ||
} | ||
logger.info( | ||
f"Human-in-the-Loop interrupt triggered for action {decision['action']} in session {state.session_id}") | ||
|
||
Code-Builder-io marked this conversation as resolved.
Show resolved
Hide resolved
|
||
# Update state with supervisor's thinking and interrupt flag if needed | ||
updated_context = { | ||
**state.context, | ||
"supervisor_thinking": response.content, | ||
"supervisor_decision": decision, | ||
"iteration_count": iteration_count + 1, | ||
} | ||
|
||
if waiting_for_user_input: | ||
updated_context["waiting_for_user_input"] = True | ||
updated_context["interrupt_details"] = interrupt_details | ||
|
||
return { | ||
"context": { | ||
**state.context, | ||
"supervisor_thinking": response.content, | ||
"supervisor_decision": decision, | ||
"iteration_count": iteration_count + 1 | ||
}, | ||
"current_task": f"supervisor_decided_{decision['action']}" | ||
"context": updated_context, | ||
"current_task": ( | ||
f"supervisor_decided_{decision['action']}" | ||
if not waiting_for_user_input else "waiting_for_user_input" | ||
), | ||
**( | ||
{"final_response": interrupt_details["prompt"], "requires_human_review": True} | ||
if waiting_for_user_input else {} | ||
) | ||
} | ||
Comment on lines
+54
to
90
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The HIL workflow is intended to be a separate handler as other nodes like faq_tool, web_search... |
||
|
||
def _parse_supervisor_decision(response: str) -> Dict[str, Any]: | ||
|
Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
@@ -6,6 +6,8 @@ | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
from app.core.orchestration.queue_manager import AsyncQueueManager | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
from app.agents.devrel.nodes.summarization import store_summary_to_database | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
from langsmith import traceable | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
from app.database.weaviate.operations import WeaviateAgentStateOperations | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
logger = logging.getLogger(__name__) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
@@ -16,8 +18,21 @@ def __init__(self, queue_manager: AsyncQueueManager): | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
self.queue_manager = queue_manager | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
self.devrel_agent = DevRelAgent() | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
self.active_sessions: Dict[str, AgentState] = {} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
self._register_handlers() | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
self.weaviate_agent_state_ops = WeaviateAgentStateOperations() | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
async def load_agent_state(self, session_id): | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
state = self.active_sessions.get(session_id) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
if state: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
return state | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
state = await self.weaviate_agent_state_ops.load_agent_state(session_id) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
if state: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
self.active_sessions[session_id] = state | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
return state | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
async def save_agent_state(self, agent_state): | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
self.active_sessions[agent_state.session_id] = agent_state | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
await self.weaviate_agent_state_ops.create_or_update_agent_state(agent_state) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
def _register_handlers(self): | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
"""Register message handlers""" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
@@ -26,34 +41,42 @@ def _register_handlers(self): | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
@traceable(name="devrel_request_coordination", run_type="chain") | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
async def _handle_devrel_request(self, message_data: Dict[str, Any]): | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
"""Handle DevRel agent requests""" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
try: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
# Extract memory thread ID (user_id for Discord) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
memory_thread_id = message_data.get("memory_thread_id") or message_data.get("user_id", "") | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
session_id = str(uuid.uuid4()) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
initial_state = AgentState( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
session_id=session_id, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
user_id=message_data.get("user_id", ""), | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
platform=message_data.get("platform", "discord"), | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
thread_id=message_data.get("thread_id"), | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
channel_id=message_data.get("channel_id"), | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
context={ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
"original_message": message_data.get("content", ""), | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
"classification": message_data.get("classification", {}), | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
"author": message_data.get("author", {}) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
# Run agent | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
logger.info(f"Running DevRel agent for session {session_id} with memory thread {memory_thread_id}") | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
result_state = await self.devrel_agent.run(initial_state, memory_thread_id) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
# Check if thread timeout was reached during processing | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
session_id = message_data.get("session_id") # Try to reuse if provided | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
# Attempt to load existing state for this session, else create new | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
agent_state = None | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
if session_id: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
agent_state = await self.load_agent_state(session_id) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
if not agent_state: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
session_id = str(uuid.uuid4()) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
agent_state = AgentState( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
session_id=session_id, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
user_id=message_data.get("user_id", ""), | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
platform=message_data.get("platform", "discord"), | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
thread_id=message_data.get("thread_id"), | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
channel_id=message_data.get("channel_id"), | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
context={ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
"original_message": message_data.get("content", ""), | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
"classification": message_data.get("classification", {}), | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
"author": message_data.get("author", {}) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Comment on lines
+46
to
+67
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 💡 Verification agent 🧩 Analysis chainVerify message ingestion on resumed sessions. When reusing an existing AgentState, the new user message isn’t added here. If the graph (or DevRelAgent) reliably appends the incoming message to state.messages, you’re fine; otherwise replies may lack the latest user input. Run this to confirm where new user messages are appended: 🏁 Script executed: #!/bin/bash
# Look for code that appends the current inbound message to AgentState.messages
rg -nP -C3 '\b(messages|state\.messages)\b.*(append|add|extend)' --glob '!**/node_modules/**' --glob '!**/dist/**'
# Inspect DevRel agent graph nodes handling inbound messages
rg -nP -C3 '\boriginal_message\b|\bHumanMessage\b|\badd_message\b|\bmessages\[-1\]' backend/app Length of output: 26745 Critical missing message ingestion on resumed sessions Our search didn’t find any place where the incoming user message is appended to Please add an explicit append of the inbound message immediately after loading or creating the if session_id:
agent_state = await self.load_agent_state(session_id)
if not agent_state:
session_id = str(uuid.uuid4())
agent_state = AgentState(
session_id=session_id,
user_id=message_data.get("user_id", ""),
platform=message_data.get("platform", "discord"),
thread_id=message_data.get("thread_id"),
channel_id=message_data.get("channel_id"),
context={
"original_message": message_data.get("content", ""),
"classification": message_data.get("classification", {}),
"author": message_data.get("author", {})
}
)
+ # Ingest the current user message into the conversation history
+ from datetime import datetime
+ agent_state.messages.append({
+ "role": "user",
+ "content": message_data.get("content", ""),
+ "timestamp": datetime.utcnow().isoformat()
+ })
📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents
Comment on lines
+48
to
+67
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Critical: latest inbound user message is never appended to AgentState.messages. On resumed sessions, downstream nodes will keep seeing the stale Insert ingestion just after the new-or-loaded state is established (right before the log at Line 68): if not agent_state:
session_id = str(uuid.uuid4())
agent_state = AgentState(
session_id=session_id,
user_id=message_data.get("user_id", ""),
platform=message_data.get("platform", "discord"),
thread_id=message_data.get("thread_id"),
channel_id=message_data.get("channel_id"),
context={
"original_message": message_data.get("content", ""),
"classification": message_data.get("classification", {}),
"author": message_data.get("author", {})
}
)
+ # Ingest the current user message into the conversation history
+ agent_state.messages.append({
+ "role": "user",
+ "content": message_data.get("content", ""),
+ "timestamp": datetime.utcnow().isoformat()
+ })
+ agent_state.interaction_count += 1
+ agent_state.last_interaction_time = datetime.utcnow() Outside this hunk, add the import: from datetime import datetime |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
logger.info( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
f"Running DevRel agent for session {agent_state.session_id} with memory thread {memory_thread_id}") | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
result_state = await self.devrel_agent.run(agent_state, memory_thread_id) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Comment on lines
+68
to
+71
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 💡 Verification agent 🧩 Analysis chainVerify alignment with DevRelAgent’s InMemorySaver memory. Per your prior design (learned context: DevRelAgent uses an InMemorySaver with thread-based conversation management), ensure the ingested message also flows into the DevRelAgent’s thread memory keyed by 🏁 Script executed: #!/bin/bash
# 1) Confirm where DevRelAgent persists/reads conversation memory for a thread
rg -nP -C3 '\bInMemorySaver\b|\bConversationBuffer\b|\bmemory\b|\bthread\b' backend/app
# 2) Confirm whether the inbound message is appended to DevRelAgent memory on each request
rg -nP -C3 '\b(messages|state\.messages)\b.*(append|add|extend)|add_message|HumanMessage' backend/app
# 3) Verify how memory_thread_id is used to read/write memory
rg -nP -C3 '\bmemory_thread_id\b' backend/app Length of output: 45649 Ensure incoming messages are saved to DevRelAgent’s thread memory Our grep of the codebase shows that while DevRelAgent instantiates an InMemorySaver ( • In backend/app/agents/devrel/agent.py, verify that Tagging as critical: until message ingestion into thread memory is implemented, the DevRelAgent will not maintain a consistent conversation history. 🤖 Prompt for AI Agents
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
# Save updated state after agent run | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
await self.save_agent_state(result_state) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
# Handle memory timeout if reached | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
if result_state.memory_timeout_reached: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
await self._handle_memory_timeout(memory_thread_id, result_state) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
# Send response back to platform | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
# Send response back to platform if present | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
if result_state.final_response: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
await self._send_response_to_platform(message_data, result_state.final_response) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
@@ -111,7 +134,7 @@ async def _send_response_to_platform(self, original_message: Dict[str, Any], res | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
"thread_id": original_message.get("thread_id"), | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
"channel_id": original_message.get("channel_id"), | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
"response": response, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
"original_message_id": original_message.get("id") | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
"original_message_id": original_message.get("id"), | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
await self.queue_manager.enqueue(response_message) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
@@ -121,4 +144,10 @@ async def _send_response_to_platform(self, original_message: Dict[str, Any], res | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
async def _send_error_response(self, original_message: Dict[str, Any], error_message: str): | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
"""Send error response to platform""" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
await self._send_response_to_platform(original_message, error_message) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
session_id = original_message.get("session_id") or str(uuid.uuid4()) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
await self._send_response_to_platform( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
original_message, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
error_message, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
session_id=session_id, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
context={} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The HIL workflow is intended to be a separate handler as other nodes like
faq_tool
,web_search
...No need of HIL support in the decision router itself.