Skip to content

Commit 939dcd5

Browse files
committed
Remove approval examples due to bug, refine handoff example
1 parent c3ac6aa commit 939dcd5

7 files changed

Lines changed: 55 additions & 456 deletions

File tree

README.md

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -229,7 +229,6 @@ You can run the examples in this repository by executing the scripts in the `exa
229229
| [workflow_hitl_checkpoint.py](examples/workflow_hitl_checkpoint.py) | Content review with `FileCheckpointStorage` — pause, exit process, and resume from checkpoint. |
230230
| [workflow_hitl_checkpoint_pg.py](examples/workflow_hitl_checkpoint_pg.py) | Same content review workflow with a custom `PostgresCheckpointStorage` backend. |
231231
| [workflow_hitl_handoff.py](examples/workflow_hitl_handoff.py) | Interactive handoff (no autonomous mode) — framework pauses for user input via `HandoffAgentUserRequest`. |
232-
| [workflow_hitl_handoff_approval.py](examples/workflow_hitl_handoff_approval.py) | Handoff with user input + tool approval combined in the same event loop. |
233232
| [workflow_hitl_magentic.py](examples/workflow_hitl_magentic.py) | Magentic orchestration with plan review — human can approve or revise the plan before execution. |
234233
| [agent_otel_aspire.py](examples/agent_otel_aspire.py) | An agent with OpenTelemetry tracing, metrics, and structured logs exported to the [Aspire Dashboard](https://aspire.dev/dashboard/standalone/). |
235234
| [agent_otel_appinsights.py](examples/agent_otel_appinsights.py) | An agent with OpenTelemetry tracing, metrics, and structured logs exported to [Azure Application Insights](https://learn.microsoft.com/azure/azure-monitor/app/app-insights-overview). Requires Azure provisioning via `azd provision`. |

examples/spanish/README.md

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -224,7 +224,6 @@ Puedes ejecutar los ejemplos en este repositorio ejecutando los scripts en el di
224224
| [workflow_hitl_checkpoint.py](workflow_hitl_checkpoint.py) | Revisión de contenido con `FileCheckpointStorage` — pausar, salir del proceso y reanudar desde checkpoint. |
225225
| [workflow_hitl_checkpoint_pg.py](workflow_hitl_checkpoint_pg.py) | Mismo workflow de revisión con un backend personalizado `PostgresCheckpointStorage`. |
226226
| [workflow_hitl_handoff.py](workflow_hitl_handoff.py) | Handoff interactivo (sin modo autónomo) — el framework pausa para entrada del usuario vía `HandoffAgentUserRequest`. |
227-
| [workflow_hitl_handoff_approval.py](workflow_hitl_handoff_approval.py) | Handoff con entrada de usuario + aprobación de herramientas combinados en el mismo bucle de eventos. |
228227
| [workflow_hitl_magentic.py](workflow_hitl_magentic.py) | Orquestación Magentic con revisión de plan — el humano puede aprobar o revisar el plan antes de la ejecución. |
229228
| [agent_otel_aspire.py](agent_otel_aspire.py) | Un agente con trazas, métricas y logs estructurados de OpenTelemetry exportados al [Aspire Dashboard](https://aspire.dev/dashboard/standalone/). |
230229
| [agent_otel_appinsights.py](agent_otel_appinsights.py) | Un agente con trazas, métricas y logs estructurados de OpenTelemetry exportados a [Azure Application Insights](https://learn.microsoft.com/azure/azure-monitor/app/app-insights-overview). Requiere aprovisionamiento de Azure con `azd provision`. |

examples/spanish/workflow_hitl_handoff.py

Lines changed: 24 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,9 @@
1414
import asyncio
1515
import os
1616
import sys
17-
from typing import Any
17+
from typing import Annotated, Any
1818

19-
from agent_framework import Agent, AgentResponse, AgentResponseUpdate
19+
from agent_framework import Agent, AgentResponse, AgentResponseUpdate, tool
2020
from agent_framework.openai import OpenAIChatClient
2121
from agent_framework.orchestrations import HandoffAgentUserRequest, HandoffBuilder
2222
from azure.identity.aio import DefaultAzureCredential, get_bearer_token_provider
@@ -47,6 +47,18 @@
4747
)
4848

4949

50+
# --- Herramientas ---
51+
52+
53+
@tool
54+
def process_return(
55+
order_number: Annotated[str, "The 3-digit order number"],
56+
return_type: Annotated[str, "Either 'refund' or 'replacement'"],
57+
) -> str:
58+
"""Process a product return for the given order."""
59+
return f"Return processed for order {order_number}: {return_type} approved. Confirmation email sent."
60+
61+
5062
# --- Agentes ---
5163

5264
triage_agent = Agent(
@@ -56,6 +68,8 @@
5668
"Eres un agente de triaje de soporte al cliente. Saluda al cliente, entiende su problema "
5769
"y transfiere al especialista correcto: order_agent para consultas de pedidos, "
5870
"return_agent para devoluciones. No puedes manejar problemas específicos tú mismo — siempre transfiere. "
71+
"Si un especialista acaba de terminar de ayudar, pregunta al cliente si necesita algo más "
72+
"— NO reenvíes al mismo especialista. "
5973
"NO pidas información de contacto, correo electrónico ni número de teléfono. "
6074
"NO digas 'Adiós' hasta que el cliente confirme explícitamente que no tiene más preguntas."
6175
),
@@ -65,7 +79,7 @@
6579
client=client,
6680
name="order_agent",
6781
instructions=(
68-
"Te encargas de consultas sobre el estado de pedidos. Ayuda al cliente con su pedido. "
82+
"Eres el especialista en seguimiento de pedidos. Ayuda al cliente a verificar el estado de su pedido. "
6983
"Cuando termines, transfiere de vuelta a triage_agent."
7084
),
7185
)
@@ -74,10 +88,12 @@
7488
client=client,
7589
name="return_agent",
7690
instructions=(
77-
"Te encargas de devoluciones de productos. Ayuda al cliente a iniciar una devolución. "
91+
"Eres el especialista en devoluciones. Ayuda al cliente a iniciar una devolución. "
7892
"Los únicos datos que necesitas son el número de pedido (3 dígitos) y si quieren un reembolso o reemplazo. "
79-
"Mantenlo simple y rápido. Cuando termines, transfiere de vuelta a triage_agent."
93+
"Mantenlo simple y rápido. Una vez que el cliente confirme, llama a process_return para completar la devolución. "
94+
"Después de procesar la devolución, transfiere de vuelta a triage_agent."
8095
),
96+
tools=[process_return],
8197
)
8298

8399

@@ -131,11 +147,9 @@ async def main() -> None:
131147
if isinstance(request_event.data, HandoffAgentUserRequest):
132148
# Muestra la respuesta del agente
133149
agent_response = request_event.data.agent_response
134-
if agent_response.messages:
135-
for msg in agent_response.messages[-3:]:
136-
if msg.text:
137-
speaker = msg.author_name or msg.role
138-
print(f"🤖 {speaker}: {msg.text}")
150+
for msg in agent_response.messages:
151+
if msg.text:
152+
print(f"🤖 {msg.author_name}: {msg.text}")
139153

140154
# Obtiene la entrada del usuario
141155
user_input = input("\n👤 Tú: ").strip()

examples/spanish/workflow_hitl_handoff_approval.py

Lines changed: 0 additions & 197 deletions
This file was deleted.

examples/workflow_hitl_handoff.py

Lines changed: 24 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,9 @@
1414
import asyncio
1515
import os
1616
import sys
17-
from typing import Any
17+
from typing import Annotated, Any
1818

19-
from agent_framework import Agent, AgentResponse, AgentResponseUpdate
19+
from agent_framework import Agent, AgentResponse, AgentResponseUpdate, tool
2020
from agent_framework.openai import OpenAIChatClient
2121
from agent_framework.orchestrations import HandoffAgentUserRequest, HandoffBuilder
2222
from azure.identity.aio import DefaultAzureCredential, get_bearer_token_provider
@@ -47,6 +47,18 @@
4747
)
4848

4949

50+
# --- Tools ---
51+
52+
53+
@tool
54+
def process_return(
55+
order_number: Annotated[str, "The 3-digit order number"],
56+
return_type: Annotated[str, "Either 'refund' or 'replacement'"],
57+
) -> str:
58+
"""Process a product return for the given order."""
59+
return f"Return processed for order {order_number}: {return_type} approved. Confirmation email sent."
60+
61+
5062
# --- Agents ---
5163

5264
triage_agent = Agent(
@@ -56,6 +68,8 @@
5668
"You are a customer-support triage agent. Greet the customer, understand their issue, "
5769
"and hand off to the right specialist: order_agent for order inquiries, "
5870
"return_agent for returns. You cannot handle specific issues yourself — always hand off. "
71+
"If a specialist has just finished helping, ask the customer if there is anything else "
72+
"they need help with — do NOT re-route to the same specialist. "
5973
"Do NOT ask for contact information, email, or phone number. "
6074
"Do NOT say 'Goodbye' until the customer explicitly confirms they have no more questions."
6175
),
@@ -65,7 +79,7 @@
6579
client=client,
6680
name="order_agent",
6781
instructions=(
68-
"You handle order status inquiries. Help the customer with their order. "
82+
"You are the order tracking specialist. Help the customer check order status. "
6983
"When done, hand off back to triage_agent."
7084
),
7185
)
@@ -74,18 +88,16 @@
7488
client=client,
7589
name="return_agent",
7690
instructions=(
77-
"You handle product returns. Help the customer initiate a return. "
91+
"You are the returns specialist. Help the customer initiate a return. "
7892
"The only details you need are the order number (3 digits) and whether they want a refund or replacement. "
79-
"Keep it simple and fast. When done, hand off back to triage_agent."
93+
"Keep it simple and fast. Once the customer confirms, call process_return to complete the return. "
94+
"After the return is processed, hand off back to triage_agent."
8095
),
96+
tools=[process_return],
8197
)
8298

8399

84-
# --- Main ---
85-
86-
87100
# --- Workflow ---
88-
89101
workflow = (
90102
HandoffBuilder(
91103
name="customer_support",
@@ -131,11 +143,9 @@ async def main() -> None:
131143
if isinstance(request_event.data, HandoffAgentUserRequest):
132144
# Show agent's response
133145
agent_response = request_event.data.agent_response
134-
if agent_response.messages:
135-
for msg in agent_response.messages[-3:]:
136-
if msg.text:
137-
speaker = msg.author_name or msg.role
138-
print(f"🤖 {speaker}: {msg.text}")
146+
for msg in agent_response.messages:
147+
if msg.text:
148+
print(f"🤖 {msg.author_name}: {msg.text}")
139149

140150
# Get user input
141151
user_input = input("\n👤 You: ").strip()

0 commit comments

Comments
 (0)