Skip to content

Commit cd64cd7

Browse files
committed
Merge branch 'dev' into release
2 parents 4282d71 + 1a1a6c8 commit cd64cd7

File tree

4 files changed

+32
-19
lines changed

4 files changed

+32
-19
lines changed

api/agent/__init__.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,7 @@ async def get_agent(id: str):
107107
def send_agent_status(connection_id: str, name: str, call_id: str) -> AgentUpdateEvent:
108108
global connections
109109

110-
async def status_fn(
110+
async def send_status(
111111
id: str,
112112
status: str,
113113
information: str | None = None,
@@ -140,7 +140,7 @@ async def status_fn(
140140
print(f"Agent {name} ({id}) - {status}")
141141

142142
# return status function
143-
return status_fn
143+
return send_status
144144

145145

146146
class FunctionCall(BaseModel):

api/agent/handler.py

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import inspect
22
import json
33
from typing import Any, Union
4+
from prompty.tracer import trace
45

56
from azure.ai.projects.models import (
67
AsyncAgentEventHandler,
@@ -31,6 +32,7 @@ def __init__(
3132
self.project_client = project_client
3233
self.history: list[dict[str, Any]] = []
3334

35+
@trace(name="send_agent_status")
3436
async def add_message(
3537
self,
3638
message: Union[ThreadMessage, ThreadRun, RunStep],
@@ -161,14 +163,14 @@ async def execute_tool_call(self, tool_call: RequiredFunctionToolCall) -> Any:
161163
arguments = json.loads(tool_call.function.arguments)
162164
except json.JSONDecodeError as e:
163165
raise ValueError(f"Invalid JSON arguments: {e}") from e
164-
166+
165167
if function_name not in self.tools:
166168
raise ValueError(f"Function {function_name} not found in tools.")
167-
169+
168170
function = self.tools[function_name]
169171
if not inspect.iscoroutinefunction(function.func):
170172
raise ValueError(f"Function {function_name} is not a coroutine function (or awaitable).")
171-
173+
172174
arguments["notify"] = self.notify
173175
# Implement the logic to execute the tool call here
174176
# This is a placeholder implementation and should be replaced with actual logic

api/voice/session.py

Lines changed: 15 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,7 @@ async def update_realtime_session(
106106
create_response=True,
107107
interrupt_response=True,
108108
)
109-
109+
110110
elif detection_type == "server_vad":
111111
vad = SessionTurnDetection(
112112
type=detection_type,
@@ -119,7 +119,7 @@ async def update_realtime_session(
119119
f"Invalid detection type: {detection_type}. "
120120
"Must be 'semantic_vad' or 'server_vad'."
121121
)
122-
122+
123123
session: Session = Session(
124124
input_audio_format="pcm16",
125125
turn_detection=vad,
@@ -142,12 +142,15 @@ async def update_realtime_session(
142142
@trace
143143
async def receive_realtime(self):
144144
# signature = "api.session.RealtimeSession.receive_realtime"
145-
#while self.realtime is not None:
145+
# while self.realtime is not None:
146146
async for event in self.realtime:
147147
if "delta" not in event.type:
148148
print(event.type)
149149
self.active = True
150-
if self.realtime is None or self.connection.state != WebSocketState.CONNECTED:
150+
if (
151+
self.realtime is None
152+
or self.connection.state != WebSocketState.CONNECTED
153+
):
151154
break
152155

153156
match event.type:
@@ -167,9 +170,7 @@ async def receive_realtime(self):
167170
event
168171
)
169172
case "conversation.item.input_audio_transcription.delta":
170-
await self._conversation_item_input_audio_transcription_delta(
171-
event
172-
)
173+
await self._conversation_item_input_audio_transcription_delta(event)
173174
case "conversation.item.input_audio_transcription.failed":
174175
await self._conversation_item_input_audio_transcription_failed(
175176
event
@@ -221,7 +222,6 @@ async def receive_realtime(self):
221222
f"Unhandled event type {event.type}",
222223
)
223224

224-
225225
@trace(name="error")
226226
async def _handle_error(self, event: ErrorEvent):
227227
print("Error event", event.error)
@@ -249,11 +249,13 @@ async def _conversation_item_input_audio_transcription_completed(
249249
if event.transcript is None or len(event.transcript.strip()) == 0:
250250
return
251251

252-
await self.connection.send_update(Update.message(
253-
id=event.item_id,
254-
role="user",
255-
content=event.transcript.strip(),
256-
))
252+
await self.connection.send_update(
253+
Update.message(
254+
id=event.item_id,
255+
role="user",
256+
content=event.transcript.strip(),
257+
)
258+
)
257259

258260
if self.thread_id is not None:
259261
await create_thread_message(

web/app/routes/app.tsx

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -181,7 +181,16 @@ export default function Home() {
181181
break;
182182
case "agent":
183183
effort?.addEffort(serverEvent);
184-
if (serverEvent.content) {
184+
if(serverEvent.status.toLowerCase().includes("failed")) {
185+
await sendRealtime({
186+
id: serverEvent.id,
187+
type: "function_completion",
188+
call_id: serverEvent.call_id,
189+
output: `The ${serverEvent.name} has failed. Please let the user know there may be issues with this agent in the service and are happy to help in any other way available to you.`,
190+
});
191+
break;
192+
}
193+
if (serverEvent.output && serverEvent.content) {
185194
addOutput(
186195
serverEvent.name.toLowerCase().replaceAll(" ", "_"),
187196
serverEvent.name,

0 commit comments

Comments
 (0)