Skip to content

Commit 4834124

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 b456f35 commit 4834124

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
@@ -33,6 +33,7 @@
3333
from ax.core.data import Data
3434
from ax.core.experiment import Experiment
3535
from ax.core.generator_run import GeneratorRun
36+
from ax.core.llm_provider import LLMMessage
3637
from ax.core.metric import Metric
3738
from ax.core.multi_type_experiment import MultiTypeExperiment
3839
from ax.core.objective import MultiObjective, Objective, ScalarizedObjective
@@ -222,6 +223,10 @@ def _init_experiment_from_sqa(
222223
# `experiment_sqa.properties` is `sqlalchemy.ext.mutable.MutableDict`
223224
# so need to convert it to regular dict.
224225
properties = dict(experiment_sqa.properties or {})
226+
if Keys.LLM_MESSAGES in properties:
227+
properties[Keys.LLM_MESSAGES] = [
228+
LLMMessage(**m) for m in properties[Keys.LLM_MESSAGES]
229+
]
225230
pruning_target = (
226231
self._get_pruning_target_parameterization_from_experiment_properties(
227232
properties=properties
@@ -286,6 +291,10 @@ def _init_mt_experiment_from_sqa(
286291
) -> MultiTypeExperiment:
287292
"""First step of conversion within experiment_from_sqa."""
288293
properties = dict(experiment_sqa.properties or {})
294+
if Keys.LLM_MESSAGES in properties:
295+
properties[Keys.LLM_MESSAGES] = [
296+
LLMMessage(**m) for m in properties[Keys.LLM_MESSAGES]
297+
]
289298
pruning_target = (
290299
self._get_pruning_target_parameterization_from_experiment_properties(
291300
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
@@ -29,6 +30,7 @@
2930
from ax.core.evaluations_to_data import DataType
3031
from ax.core.experiment import Experiment
3132
from ax.core.generator_run import GeneratorRun
33+
from ax.core.llm_provider import LLMMessage
3234
from ax.core.metric import Metric
3335
from ax.core.multi_type_experiment import MultiTypeExperiment
3436
from ax.core.objective import MultiObjective, Objective, ScalarizedObjective
@@ -239,6 +241,11 @@ def experiment_to_sqa(self, experiment: Experiment) -> SQAExperiment:
239241
properties["pruning_target_parameterization"] = arm_to_dict(
240242
oc.pruning_target_parameterization
241243
)
244+
if Keys.LLM_MESSAGES in properties:
245+
properties[Keys.LLM_MESSAGES] = [
246+
dataclasses.asdict(m) if isinstance(m, LLMMessage) else m
247+
for m in properties[Keys.LLM_MESSAGES]
248+
]
242249

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

0 commit comments

Comments
 (0)