Skip to content

Commit 6217b11

Browse files
fix: make models serializable for telemetry
1 parent 19c8968 commit 6217b11

2 files changed

Lines changed: 83 additions & 14 deletions

File tree

src/askui/models/models.py

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -195,6 +195,32 @@ def act(
195195
""" # noqa: E501
196196
raise NotImplementedError
197197

198+
def to_telemetry_dict(self) -> dict[str, str]:
199+
"""Return a JSON-serializable representation for telemetry.
200+
201+
For ActModels, this includes the model_id and MessagesApi class name.
202+
203+
Returns:
204+
dict[str, str]: A dictionary with telemetry information about this model.
205+
Includes: "type", "class", "model_id", "messages_api".
206+
207+
Example:
208+
```python
209+
{
210+
"type": "act_model",
211+
"class": "AskUIAgent",
212+
"model_id": "claude-sonnet-4-20250514",
213+
"messages_api": "AnthropicMessagesApi"
214+
}
215+
```
216+
"""
217+
return {
218+
"type": "act_model",
219+
"class": self.__class__.__name__,
220+
"model_id": self.__getattribute__("_model_id" or "-"),
221+
"messages_api": self._messages_api.__class__.__name__, # type: ignore[attr-defined]
222+
}
223+
198224

199225
class GetModel(abc.ABC):
200226
"""Abstract base class for models that can extract information from images and PDFs.
@@ -247,6 +273,28 @@ def get(
247273
"""
248274
raise NotImplementedError
249275

276+
def to_telemetry_dict(self) -> dict[str, str]:
277+
"""Return a JSON-serializable representation for telemetry.
278+
279+
For GetModels, this includes the class name.
280+
281+
Returns:
282+
dict[str, str]: A dictionary with telemetry information about this model.
283+
Includes: "type", "class".
284+
285+
Example:
286+
```python
287+
{
288+
"type": "get_model",
289+
"class": "AskUiGeminiGetModel"
290+
}
291+
```
292+
"""
293+
return {
294+
"type": "get_model",
295+
"class": self.__class__.__name__,
296+
}
297+
250298

251299
class LocateModel(abc.ABC):
252300
"""Abstract base class for models that can locate UI elements in images.
@@ -312,6 +360,28 @@ def locate_all_elements(
312360
"""
313361
raise NotImplementedError
314362

363+
def to_telemetry_dict(self) -> dict[str, str]:
364+
"""Return a JSON-serializable representation for telemetry.
365+
366+
For LocateModels, this includes the class name.
367+
368+
Returns:
369+
dict[str, str]: A dictionary with telemetry information about this model.
370+
Includes: "type", "class".
371+
372+
Example:
373+
```python
374+
{
375+
"type": "locate_model",
376+
"class": "AskUiPtaLocateModel"
377+
}
378+
```
379+
"""
380+
return {
381+
"type": "locate_model",
382+
"class": self.__class__.__name__,
383+
}
384+
315385

316386
Model = ActModel | GetModel | LocateModel
317387
"""Union type of all abstract model classes.

src/askui/telemetry/telemetry.py

Lines changed: 13 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -204,25 +204,24 @@ def wrapper(*args: P.args, **kwargs: P.kwargs) -> R: # noqa: C901
204204
)
205205
if exclude_first_arg:
206206
processed_args = processed_args[1:] if processed_args else ()
207-
processed_args = tuple(
208-
arg.model_dump()
209-
if isinstance(arg, BaseModel)
210-
else str(arg)
211-
if inspect.isclass(arg)
212-
else arg
213-
for arg in processed_args
214-
)
207+
208+
def _serialize_arg(arg: Any) -> Any:
209+
if to_telemetry := getattr(arg, "to_telemetry_dict", None):
210+
if callable(to_telemetry):
211+
return to_telemetry()
212+
if isinstance(arg, BaseModel):
213+
return arg.model_dump()
214+
if inspect.isclass(arg):
215+
return str(arg)
216+
return arg
217+
218+
processed_args = tuple(_serialize_arg(arg) for arg in processed_args)
215219
processed_kwargs = {
216220
k: v if k not in _exclude else self._EXCLUDE_MASK
217221
for k, v in kwargs.items()
218222
}
219223
processed_kwargs = {
220-
k: v.model_dump()
221-
if isinstance(v, BaseModel)
222-
else str(v)
223-
if inspect.isclass(v)
224-
else v
225-
for k, v in processed_kwargs.items()
224+
k: _serialize_arg(v) for k, v in processed_kwargs.items()
226225
}
227226
attributes: dict[str, Any] = {
228227
"module": module,

0 commit comments

Comments
 (0)