@@ -60,8 +60,15 @@ def _create_data_slice(
6060def _spec_kind (spec : Any ) -> str :
6161 return spec .__class__ .__name__
6262
63- def _spec_dump (spec : Any ) -> dict [str , Any ]:
64- return spec .__dict__
63+ def _spec_value_dump (spec : Any ) -> Any :
64+ """Recursively dump a spec object and its nested attributes to a dictionary."""
65+ if hasattr (spec , '__dict__' ):
66+ return {k : _spec_value_dump (v ) for k , v in spec .__dict__ .items ()}
67+ elif isinstance (spec , (list , tuple )):
68+ return [_spec_value_dump (item ) for item in spec ]
69+ elif isinstance (spec , dict ):
70+ return {k : _spec_value_dump (v ) for k , v in spec .items ()}
71+ return spec
6572
6673T = TypeVar ('T' )
6774
@@ -161,7 +168,7 @@ def transform(self, fn_spec: op.FunctionSpec, /, name: str | None = None) -> Dat
161168 lambda target_scope , name :
162169 flow_builder_state .engine_flow_builder .transform (
163170 _spec_kind (fn_spec ),
164- _spec_dump (fn_spec ),
171+ _spec_value_dump (fn_spec ),
165172 args ,
166173 target_scope ,
167174 flow_builder_state .field_name_builder .build_name (
@@ -252,7 +259,7 @@ def export(self, name: str, target_spec: op.StorageSpec, /, *,
252259 {"field_name" : field_name , "metric" : metric .value }
253260 for field_name , metric in vector_index ]
254261 self ._flow_builder_state .engine_flow_builder .export (
255- name , _spec_kind (target_spec ), _spec_dump (target_spec ),
262+ name , _spec_kind (target_spec ), _spec_value_dump (target_spec ),
256263 index_options , self ._engine_data_collector )
257264
258265
@@ -293,7 +300,7 @@ def add_source(self, spec: op.SourceSpec, /, name: str | None = None) -> DataSli
293300 self ._state ,
294301 lambda target_scope , name : self ._state .engine_flow_builder .add_source (
295302 _spec_kind (spec ),
296- _spec_dump (spec ),
303+ _spec_value_dump (spec ),
297304 target_scope ,
298305 self ._state .field_name_builder .build_name (
299306 name , prefix = _to_snake_case (_spec_kind (spec ))+ '_' ),
0 commit comments