Skip to content
Merged
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
3 changes: 2 additions & 1 deletion .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -31,10 +31,11 @@ jobs:
pip install -e plugins/communication_protocols/http[dev]
pip install -e plugins/communication_protocols/mcp[dev]
pip install -e plugins/communication_protocols/text[dev]
pip install -e plugins/communication_protocols/socket[dev]

- name: Run tests with pytest
run: |
pytest core/tests/ plugins/communication_protocols/cli/tests/ plugins/communication_protocols/http/tests/ plugins/communication_protocols/mcp/tests/ plugins/communication_protocols/text/tests/ --doctest-modules --junitxml=junit/test-results.xml --cov=core/src/utcp --cov-report=xml --cov-report=html
pytest core/tests/ plugins/communication_protocols/cli/tests/ plugins/communication_protocols/http/tests/ plugins/communication_protocols/mcp/tests/ plugins/communication_protocols/text/tests/ plugins/communication_protocols/socket/tests/ --doctest-modules --junitxml=junit/test-results.xml --cov=core/src/utcp --cov-report=xml --cov-report=html

- name: Upload coverage reports to Codecov
uses: codecov/codecov-action@v3
Expand Down
3 changes: 2 additions & 1 deletion plugins/communication_protocols/mcp/pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,8 @@ dependencies = [
"pydantic>=2.0",
"mcp>=1.12",
"utcp>=1.0",
"mcp-use>=1.3"
"mcp-use>=1.3",
"langchain==0.3.27",
]
classifiers = [
"Development Status :: 4 - Beta",
Expand Down
45 changes: 44 additions & 1 deletion plugins/communication_protocols/socket/README.md
Original file line number Diff line number Diff line change
@@ -1 +1,44 @@
Find the UTCP readme at https://github.com/universal-tool-calling-protocol/python-utcp.
# UTCP Socket Plugin (UDP/TCP)

This plugin adds UDP and TCP communication protocols to UTCP 1.0.

## Running Tests

Prerequisites:
- Python 3.10+
- `pip`
- (Optional) a virtual environment

1) Install core and the socket plugin in editable mode with dev extras:

```bash
pip install -e "core[dev]"
pip install -e plugins/communication_protocols/socket[dev]
```

2) Run the socket plugin tests:

```bash
python -m pytest plugins/communication_protocols/socket/tests -v
```

3) Run a single test or filter by keyword:

```bash
# One file
python -m pytest plugins/communication_protocols/socket/tests/test_tcp_communication_protocol.py -v

# Filter by keyword (e.g., delimiter framing)
python -m pytest plugins/communication_protocols/socket/tests -k delimiter -q
```

4) Optional end-to-end sanity check (mock UDP/TCP servers):

```bash
python scripts/socket_sanity.py
```

Notes:
- On Windows, your firewall may prompt the first time tests open UDP/TCP sockets; allow access or run as admin if needed.
- Tests use `pytest-asyncio`. The dev extras installed above provide required dependencies.
- Streaming is single-chunk by design, consistent with HTTP/Text transports. Multi-chunk streaming can be added later behind provider configuration.
5 changes: 4 additions & 1 deletion plugins/communication_protocols/socket/pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -36,4 +36,7 @@ dev = [
[project.urls]
Homepage = "https://utcp.io"
Source = "https://github.com/universal-tool-calling-protocol/python-utcp"
Issues = "https://github.com/universal-tool-calling-protocol/python-utcp/issues"
Issues = "https://github.com/universal-tool-calling-protocol/python-utcp/issues"

[project.entry-points."utcp.plugins"]
socket = "utcp_socket:register"
18 changes: 18 additions & 0 deletions plugins/communication_protocols/socket/src/utcp_socket/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
from utcp.plugins.discovery import register_communication_protocol, register_call_template
from utcp_socket.tcp_communication_protocol import TCPTransport
from utcp_socket.udp_communication_protocol import UDPTransport
from utcp_socket.tcp_call_template import TCPProviderSerializer
from utcp_socket.udp_call_template import UDPProviderSerializer


def register() -> None:
# Register communication protocols
register_communication_protocol("tcp", TCPTransport())
register_communication_protocol("udp", UDPTransport())

# Register call templates and their serializers
register_call_template("tcp", TCPProviderSerializer())
register_call_template("udp", UDPProviderSerializer())


__all__ = ["register"]
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
from utcp.data.call_template import CallTemplate
from typing import Optional, Literal
from pydantic import Field
from utcp.interfaces.serializer import Serializer
from utcp.exceptions import UtcpSerializerValidationError
import traceback

class TCPProvider(CallTemplate):
"""Provider configuration for raw TCP socket tools.
Expand Down Expand Up @@ -63,7 +66,7 @@ class TCPProvider(CallTemplate):
# Delimiter-based framing options
message_delimiter: str = Field(
default='\x00',
description="Delimiter to detect end of TCP response (e.g., '\\n', '\\r\\n', '\\x00'). Used with 'delimiter' framing."
description="Delimiter to detect end of TCP response (e.g., '\n', '\r\n', '\x00'). Used with 'delimiter' framing."
)
# Fixed-length framing options
fixed_message_length: Optional[int] = Field(
Expand All @@ -77,3 +80,16 @@ class TCPProvider(CallTemplate):
)
timeout: int = 30000
auth: None = None


class TCPProviderSerializer(Serializer[TCPProvider]):
def to_dict(self, obj: TCPProvider) -> dict:
return obj.model_dump()

def validate_dict(self, data: dict) -> TCPProvider:
try:
return TCPProvider.model_validate(data)
except Exception as e:
raise UtcpSerializerValidationError(
f"Invalid TCPProvider: {e}\n{traceback.format_exc()}"
)
Loading