Skip to content

Commit 5e0a9d2

Browse files
committed
feat: add support for agent context history
1 parent d605248 commit 5e0a9d2

File tree

6 files changed

+926
-0
lines changed

6 files changed

+926
-0
lines changed

deepgram/clients/agent/__init__.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@
3838
InjectUserMessageOptions,
3939
FunctionCallResponse,
4040
AgentKeepAlive,
41+
Flags,
4142
# sub level
4243
Listen,
4344
Speak,
@@ -53,4 +54,8 @@
5354
Output,
5455
Audio,
5556
Endpoint,
57+
Context,
58+
HistoryConversationMessage,
59+
HistoryFunctionCallsMessage,
60+
FunctionCallHistory,
5661
)

deepgram/clients/agent/client.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@
3737
InjectUserMessageOptions as LatestInjectUserMessageOptions,
3838
FunctionCallResponse as LatestFunctionCallResponse,
3939
AgentKeepAlive as LatestAgentKeepAlive,
40+
Flags as LatestFlags,
4041
# sub level
4142
Listen as LatestListen,
4243
Speak as LatestSpeak,
@@ -52,6 +53,10 @@
5253
Output as LatestOutput,
5354
Audio as LatestAudio,
5455
Endpoint as LatestEndpoint,
56+
Context as LatestContext,
57+
HistoryConversationMessage as LatestHistoryConversationMessage,
58+
HistoryFunctionCallsMessage as LatestHistoryFunctionCallsMessage,
59+
FunctionCallHistory as LatestFunctionCallHistory,
5560
)
5661

5762

@@ -85,6 +90,7 @@
8590
InjectUserMessageOptions = LatestInjectUserMessageOptions
8691
FunctionCallResponse = LatestFunctionCallResponse
8792
AgentKeepAlive = LatestAgentKeepAlive
93+
Flags = LatestFlags
8894

8995
Listen = LatestListen
9096
Speak = LatestSpeak
@@ -100,3 +106,7 @@
100106
Output = LatestOutput
101107
Audio = LatestAudio
102108
Endpoint = LatestEndpoint
109+
Context = LatestContext
110+
HistoryConversationMessage = LatestHistoryConversationMessage
111+
HistoryFunctionCallsMessage = LatestHistoryFunctionCallsMessage
112+
FunctionCallHistory = LatestFunctionCallHistory

deepgram/clients/agent/v1/__init__.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@
4242
InjectUserMessageOptions,
4343
FunctionCallResponse,
4444
AgentKeepAlive,
45+
Flags,
4546
# sub level
4647
Listen,
4748
Speak,
@@ -57,4 +58,8 @@
5758
Output,
5859
Audio,
5960
Endpoint,
61+
Context,
62+
HistoryConversationMessage,
63+
HistoryFunctionCallsMessage,
64+
FunctionCallHistory,
6065
)

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

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333
InjectUserMessageOptions,
3434
FunctionCallResponse,
3535
AgentKeepAlive,
36+
Flags,
3637
# sub level
3738
Listen,
3839
Speak,
@@ -48,4 +49,8 @@
4849
Output,
4950
Audio,
5051
Endpoint,
52+
Context,
53+
HistoryConversationMessage,
54+
HistoryFunctionCallsMessage,
55+
FunctionCallHistory,
5156
)

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

Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -244,6 +244,82 @@ def __getitem__(self, key):
244244
return _dict[key]
245245

246246

247+
# History and Context classes for Function Call Context / History feature
248+
249+
@dataclass
250+
class Flags(BaseResponse):
251+
"""
252+
This class defines configuration flags for the agent settings.
253+
"""
254+
255+
history: bool = field(default=True)
256+
257+
258+
@dataclass
259+
class HistoryConversationMessage(BaseResponse):
260+
"""
261+
This class defines a conversation text message as part of the conversation history.
262+
"""
263+
264+
type: str = field(default="History")
265+
role: str = field(default="") # "user" or "assistant"
266+
content: str = field(default="")
267+
268+
269+
@dataclass
270+
class FunctionCallHistory(BaseResponse):
271+
"""
272+
This class defines a single function call in the history.
273+
"""
274+
275+
id: str = field(default="")
276+
name: str = field(default="")
277+
client_side: bool = field(default=False)
278+
arguments: str = field(default="")
279+
response: str = field(default="")
280+
281+
282+
@dataclass
283+
class HistoryFunctionCallsMessage(BaseResponse):
284+
"""
285+
This class defines function call messages as part of the conversation history.
286+
"""
287+
288+
type: str = field(default="History")
289+
function_calls: List[FunctionCallHistory] = field(default_factory=list)
290+
291+
def __post_init__(self):
292+
"""Convert dict function_calls to FunctionCallHistory objects if needed."""
293+
if self.function_calls:
294+
self.function_calls = [
295+
FunctionCallHistory.from_dict(call) if isinstance(call, dict) else call
296+
for call in self.function_calls
297+
]
298+
299+
300+
@dataclass
301+
class Context(BaseResponse):
302+
"""
303+
This class defines the conversation context including the history of messages and function calls.
304+
"""
305+
306+
messages: List[Union[HistoryConversationMessage, HistoryFunctionCallsMessage]] = field(default_factory=list)
307+
308+
def __post_init__(self):
309+
"""Convert dict messages to appropriate message objects if needed."""
310+
if self.messages:
311+
converted_messages = []
312+
for message in self.messages:
313+
if isinstance(message, dict):
314+
if "function_calls" in message:
315+
converted_messages.append(HistoryFunctionCallsMessage.from_dict(message))
316+
else:
317+
converted_messages.append(HistoryConversationMessage.from_dict(message))
318+
else:
319+
converted_messages.append(message)
320+
self.messages = converted_messages
321+
322+
247323
@dataclass
248324
class Agent(BaseResponse):
249325
"""
@@ -277,6 +353,9 @@ class Agent(BaseResponse):
277353
tags: Optional[List[str]] = field(
278354
default=None, metadata=dataclass_config(exclude=lambda f: f is None)
279355
)
356+
context: Optional[Context] = field(
357+
default=None, metadata=dataclass_config(exclude=lambda f: f is None)
358+
)
280359

281360
def __post_init__(self):
282361
"""Handle conversion of dict/list data to proper Speak objects"""
@@ -300,6 +379,8 @@ def __getitem__(self, key):
300379
_dict["speak"] = [Speak.from_dict(item) for item in _dict["speak"]]
301380
elif isinstance(_dict["speak"], dict):
302381
_dict["speak"] = Speak.from_dict(_dict["speak"])
382+
if "context" in _dict and isinstance(_dict["context"], dict):
383+
_dict["context"] = Context.from_dict(_dict["context"])
303384
return _dict[key]
304385

305386

@@ -355,13 +436,19 @@ class SettingsOptions(BaseResponse):
355436
type: str = str(AgentWebSocketEvents.Settings)
356437
audio: Audio = field(default_factory=Audio)
357438
agent: Agent = field(default_factory=Agent)
439+
flags: Optional[Flags] = field(
440+
default=None, metadata=dataclass_config(exclude=lambda f: f is None)
441+
)
358442

359443
def __getitem__(self, key):
360444
_dict = self.to_dict()
361445
if "audio" in _dict and isinstance(_dict["audio"], dict):
362446
_dict["audio"] = Audio.from_dict(_dict["audio"])
363447
if "agent" in _dict and isinstance(_dict["agent"], dict):
364448
_dict["agent"] = Agent.from_dict(_dict["agent"])
449+
if "flags" in _dict and isinstance(_dict["flags"], dict):
450+
_dict["flags"] = Flags.from_dict(_dict["flags"])
451+
return _dict[key]
365452

366453
def check(self):
367454
"""

0 commit comments

Comments
 (0)