Support http(s) URLs in vlmrun gw chat - #206
Conversation
Allow inline URL arguments for images, documents, and videos alongside local file paths. URLs are passed directly to the gateway as remote content parts (image_url, document_url, video_url) instead of being base64-encoded. Co-authored-by: Sudeep Pillai <sudeep.pillai@gmail.com>
Co-authored-by: Sudeep Pillai <sudeep.pillai@gmail.com>
| def _validate_chat_input(raw: str) -> None: | ||
| """Ensure a non-URL chat input refers to a readable local file.""" | ||
| if _is_http_url(raw): | ||
| return | ||
| path = Path(raw).expanduser() | ||
| if not path.is_file(): | ||
| console.print( | ||
| f"[red]Error:[/] Input '{raw}' is not a file. " | ||
| "Provide a local path or an http(s) URL." | ||
| ) | ||
| raise typer.Exit(1) |
There was a problem hiding this comment.
🟡 Unreadable input files now crash with a raw traceback instead of a clear error
Chat inputs are only checked for existence (path.is_file() at vlmrun/cli/_cli/gateway.py:227) and no longer for read permission, so pointing the command at a file you cannot read ends in an unhandled crash instead of a friendly message.
Impact: Users see a Python stack trace rather than a clear "cannot read file" error.
Loss of typer's readable=True validation
The argument previously declared exists=True, readable=True on a List[Path], so typer rejected unreadable paths with a clean usage error. Now _validate_chat_input (vlmrun/cli/_cli/gateway.py:222-232) only checks is_file(); the subsequent path.stat() in the tree rendering (vlmrun/cli/_cli/gateway.py:694) and path.read_bytes() in _encode_file_part (vlmrun/cli/_cli/gateway.py:195) will raise PermissionError/OSError uncaught.
| def _validate_chat_input(raw: str) -> None: | |
| """Ensure a non-URL chat input refers to a readable local file.""" | |
| if _is_http_url(raw): | |
| return | |
| path = Path(raw).expanduser() | |
| if not path.is_file(): | |
| console.print( | |
| f"[red]Error:[/] Input '{raw}' is not a file. " | |
| "Provide a local path or an http(s) URL." | |
| ) | |
| raise typer.Exit(1) | |
| def _validate_chat_input(raw: str) -> None: | |
| """Ensure a non-URL chat input refers to a readable local file.""" | |
| if _is_http_url(raw): | |
| return | |
| path = Path(raw).expanduser() | |
| if not path.is_file(): | |
| console.print( | |
| f"[red]Error:[/] Input '{raw}' is not a file. " | |
| "Provide a local path or an http(s) URL." | |
| ) | |
| raise typer.Exit(1) | |
| if not os.access(path, os.R_OK): | |
| console.print(f"[red]Error:[/] Input '{raw}' is not readable.") | |
| raise typer.Exit(1) |
Was this helpful? React with 👍 or 👎 to provide feedback.
| return Path(urlparse(url).path).suffix.lower() | ||
|
|
||
|
|
||
| def _content_part_type_for_suffix(suffix: str, mime: Optional[str] = None) -> str: |
There was a problem hiding this comment.
🟡 New code uses outdated type-hint style the repository guidelines forbid
The newly added helpers and the changed command signature use legacy typing constructs (Optional[str] at vlmrun/cli/_cli/gateway.py:156) instead of the modern syntax the repository's contributor guide mandates.
Impact: The change conflicts with the project's documented code-style requirements.
AGENTS.md modern Python style rule
AGENTS.md requires X | None over Optional[X] and built-in generics (list[T], dict[K, V]) over List[T]/Dict[K, V]. New/changed code violating this: _content_part_type_for_suffix signature (vlmrun/cli/_cli/gateway.py:156), _encode_url_part/_encode_chat_input returning Dict[str, Any] (vlmrun/cli/_cli/gateway.py:205-219), _build_messages(inputs: List[str], prompt: Optional[str]) -> List[Dict[str, Any]] (vlmrun/cli/_cli/gateway.py:270), and inputs: List[str] in chat (vlmrun/cli/_cli/gateway.py:597). Note the surrounding file already uses the legacy style, so a broader cleanup may be preferred.
| def _content_part_type_for_suffix(suffix: str, mime: Optional[str] = None) -> str: | |
| def _content_part_type_for_suffix(suffix: str, mime: str | None = None) -> str: |
Was this helpful? React with 👍 or 👎 to provide feedback.
Summary
vlmrun gw chatnow accepts http(s) URLs inline alongside local file paths. URLs are sent to the gateway as remote content parts (image_url,document_url, orvideo_url) based on the URL path extension, rather than being base64-encoded.Bumps version to 0.7.2.
Usage
Changes
List[Path](withexists=True) toList[str]so URLs can be passed inline_encode_url_part,_content_part_type_from_url, etc.).mp4, etc.) now usevideo_urlcontent parts for consistency with URL inputsTesting
VLMRUN_API_KEY=vlmrun:zai-org/glm-ocrsucceededpaddleocr/pp-ocrv6succeeded