Skip to content

Commit 90e2c78

Browse files
authored
Workflows: Add payload compression encoding (#526)
Add zstd compression support for workflow payload encoding. - add payload compression config and compressed encoding option - wrap compressed payloads with self-describing msgpack metadata - decode compressed payloads independently from local encoder config - run compression before offloading and after partial encryption - keep compression dependencies optional under workflow_payload_compression - add tests for compression, encryption/offloading ordering, and invalid payloads
1 parent 9db6110 commit 90e2c78

14 files changed

Lines changed: 1014 additions & 63 deletions

File tree

docs/models/encodedpayloadoptions.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,3 +17,4 @@ This is an open enum. Unrecognized values will not fail type checks.
1717
- `"offloaded"`
1818
- `"encrypted"`
1919
- `"encrypted-partial"`
20+
- `"compressed"`

pyproject.toml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,10 @@ workflow_payload_offloading = [
4949
workflow_payload_encryption = [
5050
"cryptography>=41.0.0,<47.0.0",
5151
]
52+
workflow_payload_compression = [
53+
"msgpack>=1.1.0,<2.0.0",
54+
"zstandard>=0.25.0,<0.26",
55+
]
5256

5357

5458
[project.urls]
@@ -59,6 +63,7 @@ dev = [
5963
"invoke>=2.2.0,<3",
6064
"pyyaml>=6.0.2,<7",
6165
"mypy==1.15.0",
66+
"msgpack>=1.1.0,<2.0.0",
6267
"opentelemetry-sdk (>=1.33.1,<2.0.0)",
6368
"pylint==3.2.3",
6469
"pytest>=8.2.2,<9",
@@ -70,6 +75,7 @@ dev = [
7075
"griffe>=1.7.3,<2",
7176
"authlib>=1.5.2,<2",
7277
"websockets >=13.0",
78+
"zstandard>=0.25.0,<0.26",
7379
]
7480
lint = [
7581
"ruff>=0.11.10,<0.12",
@@ -137,6 +143,7 @@ ignore_missing_imports = true
137143
[[tool.mypy.overrides]]
138144
module = [
139145
"jsonpath.*",
146+
"msgpack.*",
140147
"typing_inspect.*",
141148
"authlib.*",
142149
"websockets.*",

src/mistralai/client/models/encodedpayloadoptions.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
"offloaded",
1212
"encrypted",
1313
"encrypted-partial",
14+
"compressed",
1415
],
1516
UnrecognizedStr,
1617
]

src/mistralai/extra/exceptions.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,10 @@ class WorkflowPayloadEncryptionException(MistralClientException):
2828
"""Workflow payload encryption exception"""
2929

3030

31+
class WorkflowPayloadCompressionException(MistralClientException):
32+
"""Workflow payload compression exception"""
33+
34+
3135
class RunException(MistralClientException):
3236
"""Conversation run errors."""
3337

src/mistralai/extra/tests/fixtures/__init__.py

Whitespace-only changes.
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
from __future__ import annotations
2+
3+
from typing import Any
4+
5+
6+
class InMemoryBlobStorage:
7+
def __init__(self) -> None:
8+
self.blobs: dict[str, bytes] = {}
9+
10+
async def __aenter__(self) -> "InMemoryBlobStorage":
11+
return self
12+
13+
async def __aexit__(self, *_args: Any) -> None:
14+
pass
15+
16+
async def upload_blob(self, key: str, content: bytes) -> str:
17+
self.blobs[key] = content
18+
return key
19+
20+
async def get_blob(self, key: str) -> bytes:
21+
return self.blobs[key]
22+
23+
async def get_blob_properties(self, key: str) -> dict[str, Any] | None:
24+
if key not in self.blobs:
25+
return None
26+
return {"size": len(self.blobs[key]), "last_modified": "test"}

0 commit comments

Comments
 (0)