Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .fernignore
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ src/deepgram/client.py
# - construct_type keyword args fix (generator uses positional, function requires keyword-only)
# - except Exception broad catch (supports custom transports, generator narrows to WebSocketException)
# - _sanitize_numeric_types in agent socket client (float→int for API)
# - optional message param on control send_ methods (send_keep_alive, send_close_stream, etc.)
# so users don't need to instantiate the type themselves for no-payload control messages
# [temporarily frozen — generator bugs in construct_type call convention and exception handling]
src/deepgram/agent/v1/socket_client.py
src/deepgram/listen/v1/socket_client.py
Expand Down
22 changes: 22 additions & 0 deletions .mcp.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
{
"mcpServers": {
"context7": {
"type": "remote",
"url": "https://context7.com/deepgram/deepgram-python-sdk",
"env": {
Comment on lines +1 to +6
Copy link

Copilot AI Apr 11, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The PR title/description indicate this change is only adding Context7 MCP server configuration, but this PR also modifies multiple WebSocket socket clients and adds new regression tests. Please update the PR description/title to reflect the behavior change (optional control-message params) or split this into separate PRs to keep the change scope clear.

Copilot uses AI. Check for mistakes.
"CONTEXT7_PUBLIC_KEY": "pk_hu7APZeIXQ14hNyaCBm0A"
Copy link

Copilot AI Apr 11, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Avoid committing API keys (even if labeled "public") directly into the repository. Consider removing the hard-coded CONTEXT7_PUBLIC_KEY value and instead reading it from the developer environment (or providing a .mcp.example.json / documentation indicating the required env var). This reduces the risk of unintended key reuse/abuse and makes rotation easier.

Suggested change
"CONTEXT7_PUBLIC_KEY": "pk_hu7APZeIXQ14hNyaCBm0A"
"CONTEXT7_PUBLIC_KEY": "${CONTEXT7_PUBLIC_KEY}"

Copilot uses AI. Check for mistakes.
}
},
"deepgram-styles": {
"type": "stdio",
"command": "npx",
"args": [
"-y",
"-p",
"@deepgram/styles",
"mcp"
],
"env": {}
}
}
}
8 changes: 4 additions & 4 deletions src/deepgram/agent/v1/socket_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -159,12 +159,12 @@ async def send_function_call_response(self, message: AgentV1SendFunctionCallResp
"""
await self._send_model(message)

async def send_keep_alive(self, message: AgentV1KeepAlive) -> None:
async def send_keep_alive(self, message: typing.Optional[AgentV1KeepAlive] = None) -> None:
"""
Send a message to the websocket connection.
The message will be sent as a AgentV1KeepAlive.
"""
await self._send_model(message)
await self._send_model(message or AgentV1KeepAlive(type="KeepAlive"))

async def send_update_prompt(self, message: AgentV1UpdatePrompt) -> None:
"""
Expand Down Expand Up @@ -292,12 +292,12 @@ def send_function_call_response(self, message: AgentV1SendFunctionCallResponse)
"""
self._send_model(message)

def send_keep_alive(self, message: AgentV1KeepAlive) -> None:
def send_keep_alive(self, message: typing.Optional[AgentV1KeepAlive] = None) -> None:
"""
Send a message to the websocket connection.
The message will be sent as a AgentV1KeepAlive.
"""
self._send_model(message)
self._send_model(message or AgentV1KeepAlive(type="KeepAlive"))

def send_update_prompt(self, message: AgentV1UpdatePrompt) -> None:
"""
Expand Down
24 changes: 12 additions & 12 deletions src/deepgram/listen/v1/socket_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -81,26 +81,26 @@ async def send_media(self, message: bytes) -> None:
"""
await self._send(message)

async def send_finalize(self, message: ListenV1Finalize) -> None:
async def send_finalize(self, message: typing.Optional[ListenV1Finalize] = None) -> None:
"""
Send a message to the websocket connection.
The message will be sent as a ListenV1Finalize.
"""
await self._send_model(message)
await self._send_model(message or ListenV1Finalize(type="Finalize"))

async def send_close_stream(self, message: ListenV1CloseStream) -> None:
async def send_close_stream(self, message: typing.Optional[ListenV1CloseStream] = None) -> None:
"""
Send a message to the websocket connection.
The message will be sent as a ListenV1CloseStream.
"""
await self._send_model(message)
await self._send_model(message or ListenV1CloseStream(type="CloseStream"))

async def send_keep_alive(self, message: ListenV1KeepAlive) -> None:
async def send_keep_alive(self, message: typing.Optional[ListenV1KeepAlive] = None) -> None:
"""
Send a message to the websocket connection.
The message will be sent as a ListenV1KeepAlive.
"""
await self._send_model(message)
await self._send_model(message or ListenV1KeepAlive(type="KeepAlive"))

async def recv(self) -> V1SocketClientResponse:
"""
Expand Down Expand Up @@ -186,26 +186,26 @@ def send_media(self, message: bytes) -> None:
"""
self._send(message)

def send_finalize(self, message: ListenV1Finalize) -> None:
def send_finalize(self, message: typing.Optional[ListenV1Finalize] = None) -> None:
"""
Send a message to the websocket connection.
The message will be sent as a ListenV1Finalize.
"""
self._send_model(message)
self._send_model(message or ListenV1Finalize(type="Finalize"))

def send_close_stream(self, message: ListenV1CloseStream) -> None:
def send_close_stream(self, message: typing.Optional[ListenV1CloseStream] = None) -> None:
"""
Send a message to the websocket connection.
The message will be sent as a ListenV1CloseStream.
"""
self._send_model(message)
self._send_model(message or ListenV1CloseStream(type="CloseStream"))

def send_keep_alive(self, message: ListenV1KeepAlive) -> None:
def send_keep_alive(self, message: typing.Optional[ListenV1KeepAlive] = None) -> None:
"""
Send a message to the websocket connection.
The message will be sent as a ListenV1KeepAlive.
"""
self._send_model(message)
self._send_model(message or ListenV1KeepAlive(type="KeepAlive"))

def recv(self) -> V1SocketClientResponse:
"""
Expand Down
8 changes: 4 additions & 4 deletions src/deepgram/listen/v2/socket_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -78,12 +78,12 @@ async def send_media(self, message: bytes) -> None:
"""
await self._send(message)

async def send_close_stream(self, message: ListenV2CloseStream) -> None:
async def send_close_stream(self, message: typing.Optional[ListenV2CloseStream] = None) -> None:
"""
Send a message to the websocket connection.
The message will be sent as a ListenV2CloseStream.
"""
await self._send_model(message)
await self._send_model(message or ListenV2CloseStream(type="CloseStream"))

async def recv(self) -> V2SocketClientResponse:
"""
Expand Down Expand Up @@ -169,12 +169,12 @@ def send_media(self, message: bytes) -> None:
"""
self._send(message)

def send_close_stream(self, message: ListenV2CloseStream) -> None:
def send_close_stream(self, message: typing.Optional[ListenV2CloseStream] = None) -> None:
"""
Send a message to the websocket connection.
The message will be sent as a ListenV2CloseStream.
"""
self._send_model(message)
self._send_model(message or ListenV2CloseStream(type="CloseStream"))

def recv(self) -> V2SocketClientResponse:
"""
Expand Down
24 changes: 12 additions & 12 deletions src/deepgram/speak/v1/socket_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -82,26 +82,26 @@ async def send_text(self, message: SpeakV1Text) -> None:
"""
await self._send_model(message)

async def send_flush(self, message: SpeakV1Flush) -> None:
async def send_flush(self, message: typing.Optional[SpeakV1Flush] = None) -> None:
"""
Send a message to the websocket connection.
The message will be sent as a SpeakV1Flush.
"""
await self._send_model(message)
await self._send_model(message or SpeakV1Flush(type="Flush"))

async def send_clear(self, message: SpeakV1Clear) -> None:
async def send_clear(self, message: typing.Optional[SpeakV1Clear] = None) -> None:
"""
Send a message to the websocket connection.
The message will be sent as a SpeakV1Clear.
"""
await self._send_model(message)
await self._send_model(message or SpeakV1Clear(type="Clear"))

async def send_close(self, message: SpeakV1Close) -> None:
async def send_close(self, message: typing.Optional[SpeakV1Close] = None) -> None:
"""
Send a message to the websocket connection.
The message will be sent as a SpeakV1Close.
"""
await self._send_model(message)
await self._send_model(message or SpeakV1Close(type="Close"))

async def recv(self) -> V1SocketClientResponse:
"""
Expand Down Expand Up @@ -187,26 +187,26 @@ def send_text(self, message: SpeakV1Text) -> None:
"""
self._send_model(message)

def send_flush(self, message: SpeakV1Flush) -> None:
def send_flush(self, message: typing.Optional[SpeakV1Flush] = None) -> None:
"""
Send a message to the websocket connection.
The message will be sent as a SpeakV1Flush.
"""
self._send_model(message)
self._send_model(message or SpeakV1Flush(type="Flush"))

def send_clear(self, message: SpeakV1Clear) -> None:
def send_clear(self, message: typing.Optional[SpeakV1Clear] = None) -> None:
"""
Send a message to the websocket connection.
The message will be sent as a SpeakV1Clear.
"""
self._send_model(message)
self._send_model(message or SpeakV1Clear(type="Clear"))

def send_close(self, message: SpeakV1Close) -> None:
def send_close(self, message: typing.Optional[SpeakV1Close] = None) -> None:
"""
Send a message to the websocket connection.
The message will be sent as a SpeakV1Close.
"""
self._send_model(message)
self._send_model(message or SpeakV1Close(type="Close"))

def recv(self) -> V1SocketClientResponse:
"""
Expand Down
Loading
Loading