Skip to content

Commit c0e864b

Browse files
authored
fix: adds inject agent message method (#555)
1 parent 20fb81c commit c0e864b

File tree

3 files changed

+248
-0
lines changed

3 files changed

+248
-0
lines changed

deepgram/clients/agent/v1/websocket/async_client.py

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -644,6 +644,30 @@ async def inject_user_message(self, options: InjectUserMessageOptions) -> bool:
644644

645645
return True
646646

647+
async def inject_agent_message(self, options: InjectAgentMessageOptions) -> bool:
648+
"""
649+
Injects an agent message to immediately trigger an agent statement.
650+
"""
651+
self._logger.spam("AsyncAgentWebSocketClient.inject_agent_message ENTER")
652+
653+
if not isinstance(options, InjectAgentMessageOptions):
654+
self._logger.error("options must be of type InjectAgentMessageOptions")
655+
self._logger.spam("AsyncAgentWebSocketClient.inject_agent_message LEAVE")
656+
return False
657+
658+
self._logger.notice("Sending InjectAgentMessage...")
659+
ret = await self.send(str(options))
660+
661+
if not ret:
662+
self._logger.error("inject_agent_message failed")
663+
self._logger.spam("AsyncAgentWebSocketClient.inject_agent_message LEAVE")
664+
return False
665+
666+
self._logger.notice("inject_agent_message succeeded")
667+
self._logger.spam("AsyncAgentWebSocketClient.inject_agent_message LEAVE")
668+
669+
return True
670+
647671
async def _close_message(self) -> bool:
648672
# TODO: No known API close message # pylint: disable=fixme
649673
# return await self.send(json.dumps({"type": "Close"}))

deepgram/clients/agent/v1/websocket/client.py

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -640,6 +640,30 @@ def inject_user_message(self, options: InjectUserMessageOptions) -> bool:
640640

641641
return True
642642

643+
def inject_agent_message(self, options: InjectAgentMessageOptions) -> bool:
644+
"""
645+
Injects an agent message to immediately trigger an agent statement.
646+
"""
647+
self._logger.spam("AgentWebSocketClient.inject_agent_message ENTER")
648+
649+
if not isinstance(options, InjectAgentMessageOptions):
650+
self._logger.error("options must be of type InjectAgentMessageOptions")
651+
self._logger.spam("AgentWebSocketClient.inject_agent_message LEAVE")
652+
return False
653+
654+
self._logger.notice("Sending InjectAgentMessage...")
655+
ret = self.send(str(options))
656+
657+
if not ret:
658+
self._logger.error("inject_agent_message failed")
659+
self._logger.spam("AgentWebSocketClient.inject_agent_message LEAVE")
660+
return False
661+
662+
self._logger.notice("inject_agent_message succeeded")
663+
self._logger.spam("AgentWebSocketClient.inject_agent_message LEAVE")
664+
665+
return True
666+
643667
def _close_message(self) -> bool:
644668
# TODO: No known API close message # pylint: disable=fixme
645669
# return self.send(json.dumps({"type": "Close"}))
Lines changed: 200 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,200 @@
1+
import pytest
2+
import json
3+
from unittest.mock import patch, MagicMock
4+
5+
from deepgram import (
6+
DeepgramClient,
7+
InjectAgentMessageOptions,
8+
)
9+
10+
class TestAgentInjectAgentMessage:
11+
"""Focused unit tests for inject_agent_message functionality"""
12+
13+
def test_inject_agent_message_options_serialization(self):
14+
"""Test JSON serialization is correct"""
15+
options = InjectAgentMessageOptions(message="Test agent message")
16+
result = json.loads(str(options))
17+
expected = {"type": "InjectAgentMessage", "message": "Test agent message"}
18+
assert result == expected
19+
20+
def test_inject_agent_message_options_default_message(self):
21+
"""Test default empty message serialization"""
22+
options = InjectAgentMessageOptions()
23+
result = json.loads(str(options))
24+
expected = {"type": "InjectAgentMessage", "message": ""}
25+
assert result == expected
26+
27+
@patch('deepgram.clients.agent.v1.websocket.client.AgentWebSocketClient.send')
28+
def test_inject_agent_message_success(self, mock_send):
29+
"""Test successful message injection"""
30+
mock_send.return_value = True
31+
32+
client = DeepgramClient("fake-key")
33+
connection = client.agent.websocket.v("1")
34+
options = InjectAgentMessageOptions(message="Hello from agent")
35+
36+
result = connection.inject_agent_message(options)
37+
38+
assert result == True
39+
mock_send.assert_called_once_with(str(options))
40+
41+
@patch('deepgram.clients.agent.v1.websocket.client.AgentWebSocketClient.send')
42+
def test_inject_agent_message_send_failure(self, mock_send):
43+
"""Test handling of send method failure"""
44+
mock_send.return_value = False
45+
46+
client = DeepgramClient("fake-key")
47+
connection = client.agent.websocket.v("1")
48+
options = InjectAgentMessageOptions(message="Hello from agent")
49+
50+
result = connection.inject_agent_message(options)
51+
52+
assert result == False
53+
mock_send.assert_called_once_with(str(options))
54+
55+
def test_inject_agent_message_invalid_type(self):
56+
"""Test error handling for invalid parameter type"""
57+
client = DeepgramClient("fake-key")
58+
connection = client.agent.websocket.v("1")
59+
60+
# Should return False for invalid type
61+
result = connection.inject_agent_message("not an options object")
62+
assert result == False
63+
64+
def test_inject_agent_message_none_parameter(self):
65+
"""Test error handling for None parameter"""
66+
client = DeepgramClient("fake-key")
67+
connection = client.agent.websocket.v("1")
68+
69+
# Should return False for None parameter
70+
result = connection.inject_agent_message(None)
71+
assert result == False
72+
73+
def test_inject_agent_message_wrong_options_type(self):
74+
"""Test error handling for wrong options type"""
75+
from deepgram import InjectUserMessageOptions
76+
77+
client = DeepgramClient("fake-key")
78+
connection = client.agent.websocket.v("1")
79+
80+
# Should return False for wrong options type
81+
wrong_options = InjectUserMessageOptions(content="test")
82+
result = connection.inject_agent_message(wrong_options)
83+
assert result == False
84+
85+
86+
class TestAsyncAgentInjectAgentMessage:
87+
"""Focused unit tests for async inject_agent_message functionality"""
88+
89+
@pytest.mark.asyncio
90+
@patch('deepgram.clients.agent.v1.websocket.async_client.AsyncAgentWebSocketClient.send')
91+
async def test_async_inject_agent_message_success(self, mock_send):
92+
"""Test successful async message injection"""
93+
mock_send.return_value = True
94+
95+
client = DeepgramClient("fake-key")
96+
connection = client.agent.asyncwebsocket.v("1")
97+
options = InjectAgentMessageOptions(message="Hello from async agent")
98+
99+
result = await connection.inject_agent_message(options)
100+
101+
assert result == True
102+
mock_send.assert_called_once_with(str(options))
103+
104+
@pytest.mark.asyncio
105+
@patch('deepgram.clients.agent.v1.websocket.async_client.AsyncAgentWebSocketClient.send')
106+
async def test_async_inject_agent_message_send_failure(self, mock_send):
107+
"""Test handling of async send method failure"""
108+
mock_send.return_value = False
109+
110+
client = DeepgramClient("fake-key")
111+
connection = client.agent.asyncwebsocket.v("1")
112+
options = InjectAgentMessageOptions(message="Hello from async agent")
113+
114+
result = await connection.inject_agent_message(options)
115+
116+
assert result == False
117+
mock_send.assert_called_once_with(str(options))
118+
119+
@pytest.mark.asyncio
120+
async def test_async_inject_agent_message_invalid_type(self):
121+
"""Test error handling for invalid parameter type in async client"""
122+
client = DeepgramClient("fake-key")
123+
connection = client.agent.asyncwebsocket.v("1")
124+
125+
# Should return False for invalid type
126+
result = await connection.inject_agent_message("not an options object")
127+
assert result == False
128+
129+
@pytest.mark.asyncio
130+
async def test_async_inject_agent_message_none_parameter(self):
131+
"""Test error handling for None parameter in async client"""
132+
client = DeepgramClient("fake-key")
133+
connection = client.agent.asyncwebsocket.v("1")
134+
135+
# Should return False for None parameter
136+
result = await connection.inject_agent_message(None)
137+
assert result == False
138+
139+
140+
class TestInjectAgentMessageIntegration:
141+
"""Integration tests comparing inject_user_message and inject_agent_message"""
142+
143+
def test_options_classes_have_different_types(self):
144+
"""Test that agent and user message options have different types"""
145+
from deepgram import InjectUserMessageOptions
146+
147+
agent_options = InjectAgentMessageOptions(message="agent message")
148+
user_options = InjectUserMessageOptions(content="user message")
149+
150+
agent_json = json.loads(str(agent_options))
151+
user_json = json.loads(str(user_options))
152+
153+
assert agent_json["type"] == "InjectAgentMessage"
154+
assert user_json["type"] == "InjectUserMessage"
155+
assert agent_json["type"] != user_json["type"]
156+
157+
def test_options_classes_have_different_message_fields(self):
158+
"""Test that agent and user message options have different field names"""
159+
from deepgram import InjectUserMessageOptions
160+
161+
agent_options = InjectAgentMessageOptions(message="agent message")
162+
user_options = InjectUserMessageOptions(content="user message")
163+
164+
agent_json = json.loads(str(agent_options))
165+
user_json = json.loads(str(user_options))
166+
167+
# Agent uses 'message' field
168+
assert "message" in agent_json
169+
assert agent_json["message"] == "agent message"
170+
171+
# User uses 'content' field
172+
assert "content" in user_json
173+
assert user_json["content"] == "user message"
174+
175+
# They should not have each other's fields
176+
assert "content" not in agent_json
177+
assert "message" not in user_json
178+
179+
@patch('deepgram.clients.agent.v1.websocket.client.AgentWebSocketClient.send')
180+
def test_both_injection_methods_exist(self, mock_send):
181+
"""Test that both injection methods exist and are callable"""
182+
from deepgram import InjectUserMessageOptions
183+
184+
mock_send.return_value = True
185+
186+
client = DeepgramClient("fake-key")
187+
connection = client.agent.websocket.v("1")
188+
189+
# Test inject_user_message exists
190+
user_options = InjectUserMessageOptions(content="user message")
191+
user_result = connection.inject_user_message(user_options)
192+
assert user_result == True
193+
194+
# Test inject_agent_message exists
195+
agent_options = InjectAgentMessageOptions(message="agent message")
196+
agent_result = connection.inject_agent_message(agent_options)
197+
assert agent_result == True
198+
199+
# Both methods should have been called
200+
assert mock_send.call_count == 2

0 commit comments

Comments
 (0)