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
20 changes: 10 additions & 10 deletions decart/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -183,72 +183,72 @@ class ImageToImageInput(DecartBaseModel):
"lucy-2.1": ModelDefinition(
name="lucy-2.1",
url_path="/v1/stream",
fps=20,
fps=30,
width=1088,
height=624,
),
"lucy-2.1-vton": ModelDefinition(
name="lucy-2.1-vton",
url_path="/v1/stream",
fps=20,
fps=30,
width=1088,
height=624,
),
"lucy-restyle-2": ModelDefinition(
name="lucy-restyle-2",
url_path="/v1/stream",
fps=22,
fps=30,
width=1280,
height=704,
),
# Latest aliases (server-side resolution)
"lucy-latest": ModelDefinition(
name="lucy-latest",
url_path="/v1/stream",
fps=20,
fps=30,
width=1088,
height=624,
),
"lucy-vton-latest": ModelDefinition(
name="lucy-vton-latest",
url_path="/v1/stream",
fps=20,
fps=30,
width=1088,
height=624,
),
"lucy-vton-2": ModelDefinition(
name="lucy-vton-2",
url_path="/v1/stream",
fps=20,
fps=30,
width=1088,
height=624,
),
"lucy-2.1-vton-2": ModelDefinition(
name="lucy-2.1-vton-2",
url_path="/v1/stream",
fps=20,
fps=30,
width=1088,
height=624,
),
"lucy-restyle-latest": ModelDefinition(
name="lucy-restyle-latest",
url_path="/v1/stream",
fps=22,
fps=30,
width=1280,
height=704,
),
# Deprecated names
"lucy-vton": ModelDefinition(
name="lucy-vton",
url_path="/v1/stream",
fps=20,
fps=30,
width=1088,
height=624,
),
"mirage_v2": ModelDefinition(
name="mirage_v2",
url_path="/v1/stream",
fps=22,
fps=30,
width=1280,
height=704,
),
Expand Down
2 changes: 2 additions & 0 deletions decart/realtime/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,8 @@ async def connect(
) -> "RealtimeClient":
ws_url = f"{base_url}{options.model.url_path}"
ws_url += f"?api_key={quote(api_key)}&model={quote(options.model.name)}"
if options.resolution is not None:
ws_url += f"&resolution={quote(options.resolution)}"

config = WebRTCConfiguration(
webrtc_url=ws_url,
Expand Down
1 change: 1 addition & 0 deletions decart/realtime/types.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,3 +18,4 @@ class RealtimeConnectOptions:
on_remote_stream: Callable[[MediaStreamTrack], None]
initial_state: Optional[ModelState] = None
customize_offer: Optional[Callable] = None
resolution: Optional[Literal["720p", "1080p"]] = None
12 changes: 6 additions & 6 deletions tests/test_models.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,20 +7,20 @@
def test_canonical_realtime_models() -> None:
model = models.realtime("lucy-restyle-2")
assert model.name == "lucy-restyle-2"
assert model.fps == 22
assert model.fps == 30
assert model.width == 1280
assert model.height == 704
assert model.url_path == "/v1/stream"

model = models.realtime("lucy-2.1")
assert model.name == "lucy-2.1"
assert model.fps == 20
assert model.fps == 30
assert model.width == 1088
assert model.height == 624

model = models.realtime("lucy-2.1-vton")
assert model.name == "lucy-2.1-vton"
assert model.fps == 20
assert model.fps == 30
assert model.width == 1088
assert model.height == 624

Expand Down Expand Up @@ -113,21 +113,21 @@ def test_latest_realtime_models() -> None:
model = models.realtime("lucy-latest")
assert model.name == "lucy-latest"
assert model.url_path == "/v1/stream"
assert model.fps == 20
assert model.fps == 30
assert model.width == 1088
assert model.height == 624

model = models.realtime("lucy-vton-latest")
assert model.name == "lucy-vton-latest"
assert model.url_path == "/v1/stream"
assert model.fps == 20
assert model.fps == 30
assert model.width == 1088
assert model.height == 624

model = models.realtime("lucy-restyle-latest")
assert model.name == "lucy-restyle-latest"
assert model.url_path == "/v1/stream"
assert model.fps == 22
assert model.fps == 30
assert model.width == 1280
assert model.height == 704

Expand Down
61 changes: 59 additions & 2 deletions tests/test_realtime_unit.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,14 +27,14 @@ def test_realtime_models_available():
"""Test that realtime models are available"""
model = models.realtime("lucy-restyle-2")
assert model.name == "lucy-restyle-2"
assert model.fps == 22
assert model.fps == 30
assert model.width == 1280
assert model.height == 704
assert model.url_path == "/v1/stream"

model2 = models.realtime("lucy-2.1")
assert model2.name == "lucy-2.1"
assert model2.fps == 20
assert model2.fps == 30
assert model2.width == 1088
assert model2.height == 624
assert model2.url_path == "/v1/stream"
Expand Down Expand Up @@ -149,6 +149,63 @@ async def test_realtime_connect_accepts_custom_model_definition():
await realtime_client.disconnect()


async def _connect_and_capture_url(resolution=None) -> str:
client = DecartClient(api_key="test-key")

with (
patch("decart.realtime.client.WebRTCManager") as mock_manager_class,
patch("decart.realtime.client.aiohttp.ClientSession") as mock_session_cls,
):
mock_manager = AsyncMock()
mock_manager.connect = AsyncMock(return_value=True)
mock_manager.is_connected = MagicMock(return_value=True)
mock_manager_class.return_value = mock_manager

mock_session = MagicMock()
mock_session.closed = False
mock_session.close = AsyncMock()
mock_session_cls.return_value = mock_session

from decart.realtime.types import RealtimeConnectOptions

kwargs = {"resolution": resolution} if resolution is not None else {}
realtime_client = await RealtimeClient.connect(
base_url=client.realtime_base_url,
api_key=client.api_key,
local_track=MagicMock(),
options=RealtimeConnectOptions(
model=models.realtime("lucy-2.1"),
on_remote_stream=lambda t: None,
**kwargs,
),
)

call_args = mock_manager_class.call_args
config = call_args[0][0] if call_args[0] else call_args[1]["configuration"]
url = config.webrtc_url

await realtime_client.disconnect()
return url


@pytest.mark.asyncio
async def test_realtime_connect_omits_resolution_when_unset():
url = await _connect_and_capture_url()
assert "resolution=" not in url


@pytest.mark.asyncio
async def test_realtime_connect_appends_resolution_720p():
url = await _connect_and_capture_url("720p")
assert "&resolution=720p" in url


@pytest.mark.asyncio
async def test_realtime_connect_appends_resolution_1080p():
url = await _connect_and_capture_url("1080p")
assert "&resolution=1080p" in url


@pytest.mark.asyncio
async def test_realtime_set_prompt_with_mock():
"""Test set_prompt with mocked WebRTC and prompt_ack"""
Expand Down
2 changes: 1 addition & 1 deletion uv.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading