|
9 | 9 | import shutil |
10 | 10 | import subprocess |
11 | 11 | from dataclasses import dataclass, field |
12 | | -from typing import Any, Awaitable, Callable, Literal, Optional, Protocol, TypedDict, cast |
| 12 | +from typing import Any, Awaitable, Callable, Literal, NotRequired, Optional, Protocol, TypedDict, cast |
13 | 13 | from urllib.parse import quote, urlparse, urlunparse |
14 | 14 |
|
15 | 15 | import aiohttp |
@@ -42,7 +42,13 @@ class LiveRunnerTrickleChannelRequest(TypedDict): |
42 | 42 | class LiveRunnerTrickleChannel(TypedDict): |
43 | 43 | name: str |
44 | 44 | channel_name: str |
| 45 | + # Public/external trickle URL. |
45 | 46 | url: str |
| 47 | + # Optional private-network URL for runner-to-orchestrator traffic. When the |
| 48 | + # runner and orchestrator share a network, such as Docker, this can bypass |
| 49 | + # public TLS/routing, but it is only present when the orchestrator is |
| 50 | + # configured to return one. |
| 51 | + internal_url: NotRequired[str] |
46 | 52 | mime_type: str |
47 | 53 |
|
48 | 54 |
|
@@ -872,7 +878,7 @@ def _is_trickle_channel_response(value: object) -> bool: |
872 | 878 | return all( |
873 | 879 | isinstance(value.get(key), str) |
874 | 880 | for key in ("name", "channel_name", "url", "mime_type") |
875 | | - ) |
| 881 | + ) and ("internal_url" not in value or isinstance(value.get("internal_url"), str)) |
876 | 882 |
|
877 | 883 |
|
878 | 884 | async def _post_empty(url: str, headers: dict[str, str], timeout: float) -> None: |
|
0 commit comments