Skip to content

Commit ec24b71

Browse files
ItsMrLinfacebook-github-bot
authored andcommitted
Handle LLMMessage serialization at the storage layer (facebook#5024)
Summary: Move `LLMMessage` dict conversion from the `experiment.llm_messages` getter/setter to the storage encoders/decoders, following Ax convention that domain objects hold domain types and serialization happens at the storage boundary. **`experiment.py`**: The setter now stores `LLMMessage` objects directly in `_properties`. The getter handles both `LLMMessage` objects (new path) and plain dicts (backward compat with previously stored data). **JSON store**: No explicit changes needed — the encoder's generic dataclass fallback auto-serializes `LLMMessage` with a `__type` tag, and `LLMMessage` is already registered in `CORE_DECODER_REGISTRY`. **SQA store**: The encoder converts `LLMMessage` → dict via `dataclasses.asdict()` in the properties copy before DB write (same pattern as `pruning_target_parameterization`). The decoder converts dicts → `LLMMessage` after loading properties, in both `_init_experiment_from_sqa` and `_init_mt_experiment_from_sqa`. Reviewed By: lena-kashtelyan Differential Revision: D96434290
1 parent d016302 commit ec24b71

File tree

2 files changed

+16
-0
lines changed

2 files changed

+16
-0
lines changed

ax/storage/sqa_store/decoder.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
from ax.core.data import Data
3333
from ax.core.experiment import Experiment
3434
from ax.core.generator_run import GeneratorRun
35+
from ax.core.llm_provider import LLMMessage
3536
from ax.core.metric import Metric
3637
from ax.core.multi_type_experiment import MultiTypeExperiment
3738
from ax.core.objective import MultiObjective, Objective, ScalarizedObjective
@@ -221,6 +222,10 @@ def _init_experiment_from_sqa(
221222
# `experiment_sqa.properties` is `sqlalchemy.ext.mutable.MutableDict`
222223
# so need to convert it to regular dict.
223224
properties = dict(experiment_sqa.properties or {})
225+
if Keys.LLM_MESSAGES in properties:
226+
properties[Keys.LLM_MESSAGES] = [
227+
LLMMessage(**m) for m in properties[Keys.LLM_MESSAGES]
228+
]
224229
pruning_target = (
225230
self._get_pruning_target_parameterization_from_experiment_properties(
226231
properties=properties
@@ -285,6 +290,10 @@ def _init_mt_experiment_from_sqa(
285290
) -> MultiTypeExperiment:
286291
"""First step of conversion within experiment_from_sqa."""
287292
properties = dict(experiment_sqa.properties or {})
293+
if Keys.LLM_MESSAGES in properties:
294+
properties[Keys.LLM_MESSAGES] = [
295+
LLMMessage(**m) for m in properties[Keys.LLM_MESSAGES]
296+
]
288297
pruning_target = (
289298
self._get_pruning_target_parameterization_from_experiment_properties(
290299
properties=properties

ax/storage/sqa_store/encoder.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66

77
# pyre-strict
88

9+
import dataclasses
910
from enum import Enum
1011
from logging import Logger
1112
from typing import Any, cast
@@ -28,6 +29,7 @@
2829
from ax.core.evaluations_to_data import DataType
2930
from ax.core.experiment import Experiment
3031
from ax.core.generator_run import GeneratorRun
32+
from ax.core.llm_provider import LLMMessage
3133
from ax.core.metric import Metric
3234
from ax.core.multi_type_experiment import MultiTypeExperiment
3335
from ax.core.objective import MultiObjective, Objective, ScalarizedObjective
@@ -238,6 +240,11 @@ def experiment_to_sqa(self, experiment: Experiment) -> SQAExperiment:
238240
properties["pruning_target_parameterization"] = arm_to_dict(
239241
oc.pruning_target_parameterization
240242
)
243+
if Keys.LLM_MESSAGES in properties:
244+
properties[Keys.LLM_MESSAGES] = [
245+
dataclasses.asdict(m) if isinstance(m, LLMMessage) else m
246+
for m in properties[Keys.LLM_MESSAGES]
247+
]
241248

242249
# pyre-ignore[9]: Expected `Base` for 1st...yping.Type[Experiment]`.
243250
experiment_class: type[SQAExperiment] = self.config.class_to_sqa_class[

0 commit comments

Comments
 (0)