History item for agent actions
| 486 | |
| 487 | |
| 488 | class AgentHistory(BaseModel): |
| 489 | """History item for agent actions""" |
| 490 | |
| 491 | model_output: AgentOutput | None |
| 492 | result: list[ActionResult] |
| 493 | state: BrowserStateHistory |
| 494 | metadata: StepMetadata | None = None |
| 495 | state_message: str | None = None |
| 496 | |
| 497 | model_config = ConfigDict(arbitrary_types_allowed=True, protected_namespaces=()) |
| 498 | |
| 499 | @staticmethod |
| 500 | def get_interacted_element(model_output: AgentOutput, selector_map: DOMSelectorMap) -> list[DOMInteractedElement | None]: |
| 501 | elements = [] |
| 502 | for action in model_output.action: |
| 503 | index = action.get_index() |
| 504 | if index is not None and index in selector_map: |
| 505 | el = selector_map[index] |
| 506 | elements.append(DOMInteractedElement.load_from_enhanced_dom_tree(el)) |
| 507 | else: |
| 508 | elements.append(None) |
| 509 | return elements |
| 510 | |
| 511 | def _filter_sensitive_data_from_string(self, value: str, sensitive_data: dict[str, str | dict[str, str]] | None) -> str: |
| 512 | """Filter out sensitive data from a string value""" |
| 513 | if not sensitive_data: |
| 514 | return value |
| 515 | |
| 516 | sensitive_values = collect_sensitive_data_values(sensitive_data) |
| 517 | |
| 518 | # If there are no valid sensitive data entries, just return the original value |
| 519 | if not sensitive_values: |
| 520 | return value |
| 521 | |
| 522 | return redact_sensitive_string(value, sensitive_values) |
| 523 | |
| 524 | def _filter_sensitive_data_from_dict( |
| 525 | self, data: dict[str, Any], sensitive_data: dict[str, str | dict[str, str]] | None |
| 526 | ) -> dict[str, Any]: |
| 527 | """Recursively filter sensitive data from a dictionary""" |
| 528 | if not sensitive_data: |
| 529 | return data |
| 530 | |
| 531 | filtered_data = {} |
| 532 | for key, value in data.items(): |
| 533 | if isinstance(value, str): |
| 534 | filtered_data[key] = self._filter_sensitive_data_from_string(value, sensitive_data) |
| 535 | elif isinstance(value, dict): |
| 536 | filtered_data[key] = self._filter_sensitive_data_from_dict(value, sensitive_data) |
| 537 | elif isinstance(value, list): |
| 538 | filtered_data[key] = [ |
| 539 | self._filter_sensitive_data_from_string(item, sensitive_data) |
| 540 | if isinstance(item, str) |
| 541 | else self._filter_sensitive_data_from_dict(item, sensitive_data) |
| 542 | if isinstance(item, dict) |
| 543 | else item |
| 544 | for item in value |
| 545 | ] |
no outgoing calls
searching dependent graphs…