new feature: frontend with separated responses
This commit is contained in:
@@ -435,6 +435,34 @@ class AgentWorkflow:
|
||||
"PAUSED",
|
||||
"WAITING_INPUT",
|
||||
}
|
||||
# The most recent MCP result is authoritative for a transaction
|
||||
# promoted after another transaction completed in the same
|
||||
# multi-intent turn. Checkpoint merge order can otherwise leave
|
||||
# the previous COMPLETED status at the top level and cause input
|
||||
# guardrails to reject the new transaction's short confirmation.
|
||||
latest_mcp_transaction = next(
|
||||
(
|
||||
result
|
||||
for result in reversed(list(state.get("mcp_results") or []))
|
||||
if isinstance(result, dict)
|
||||
and str(result.get("transaction_status") or "").strip().upper()
|
||||
in nonterminal_tx_statuses
|
||||
),
|
||||
None,
|
||||
)
|
||||
if latest_mcp_transaction:
|
||||
latest_status = str(latest_mcp_transaction.get("transaction_status") or "").strip().upper()
|
||||
tx_status = latest_status
|
||||
state["transaction_status"] = latest_status
|
||||
if not active_tx or active_tx_status not in nonterminal_tx_statuses:
|
||||
active_tx = {
|
||||
"transaction_id": str(latest_mcp_transaction.get("transaction_id") or ""),
|
||||
"tool_name": str(latest_mcp_transaction.get("tool_name") or ""),
|
||||
"arguments": dict(latest_mcp_transaction.get("arguments") or {}),
|
||||
"status": latest_status,
|
||||
}
|
||||
state["active_transaction"] = active_tx
|
||||
active_tx_status = latest_status
|
||||
# A new active transaction has precedence over terminal evidence from
|
||||
# the previous transaction in the same session. Without this guard,
|
||||
# a stale state["transaction_status"] == COMPLETED can tombstone an
|
||||
@@ -549,6 +577,7 @@ class AgentWorkflow:
|
||||
"transaction_status": state.get("transaction_status"),
|
||||
"missing_parameters": list(state.get("missing_parameters") or []),
|
||||
"active_transaction": state.get("active_transaction") or {},
|
||||
"mcp_results": list(state.get("mcp_results") or []),
|
||||
},
|
||||
)
|
||||
for _decision in decisions:
|
||||
@@ -729,7 +758,8 @@ class AgentWorkflow:
|
||||
} if decision.method == "continuity" else {},
|
||||
"pending_topics": (
|
||||
(decision.metadata or {}).get("multi_intent_plan", {}).get("operations", [])[1:]
|
||||
if (decision.metadata or {}).get("multi_intent_plan") else []
|
||||
if (decision.metadata or {}).get("multi_intent_plan")
|
||||
else list(state.get("pending_topics") or [])
|
||||
),
|
||||
}
|
||||
|
||||
@@ -953,6 +983,7 @@ class AgentWorkflow:
|
||||
"output_guardrails_already_applied": False,
|
||||
"supervisor_action": "disabled",
|
||||
"supervisor_attempt": int(state.get("supervisor_attempt", 0)),
|
||||
**drained.state_patch,
|
||||
}
|
||||
context = {
|
||||
**self._output_guardrail_context({
|
||||
@@ -1033,6 +1064,7 @@ class AgentWorkflow:
|
||||
"agent_responses": drained.agent_responses,
|
||||
"mcp_results": drained.mcp_results,
|
||||
"rag_results": drained.rag_results,
|
||||
**drained.state_patch,
|
||||
}
|
||||
|
||||
async def output_guardrails(self, state):
|
||||
|
||||
Reference in New Issue
Block a user