asteroid-odyssey 1.3.1__py3-none-any.whl → 1.3.2__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -7,9 +7,15 @@ from .client import (
7
7
  wait_for_execution_result,
8
8
  upload_execution_files,
9
9
  get_browser_session_recording,
10
+ get_agent_profiles,
11
+ get_agent_profile,
12
+ create_agent_profile,
13
+ update_agent_profile,
14
+ delete_agent_profile,
10
15
  get_last_n_execution_activities,
11
16
  add_message_to_execution,
12
17
  wait_for_agent_interaction,
18
+ get_credentials_public_key,
13
19
  AsteroidAPIError,
14
20
  ExecutionError,
15
21
  TimeoutError,
@@ -26,9 +32,15 @@ __all__ = [
26
32
  'wait_for_execution_result',
27
33
  'upload_execution_files',
28
34
  'get_browser_session_recording',
35
+ 'get_agent_profiles',
36
+ 'get_agent_profile',
37
+ 'create_agent_profile',
38
+ 'update_agent_profile',
39
+ 'delete_agent_profile',
29
40
  'get_last_n_execution_activities',
30
41
  'add_message_to_execution',
31
42
  'wait_for_agent_interaction',
43
+ 'get_credentials_public_key',
32
44
  'AsteroidAPIError',
33
45
  'ExecutionError',
34
46
  'TimeoutError',
@@ -219,7 +219,7 @@ class AsteroidClient:
219
219
  # Handle case where execution_result might be None or have invalid data
220
220
  if response.execution_result is None:
221
221
  raise AsteroidAPIError("Execution result is not available yet")
222
-
222
+
223
223
  return response.execution_result
224
224
  except ApiException as e:
225
225
  raise AsteroidAPIError(f"Failed to get execution result: {e}") from e
@@ -591,39 +591,39 @@ class AsteroidClient:
591
591
  ) -> AgentInteractionResult:
592
592
  """
593
593
  Wait for an agent interaction request or terminal state.
594
-
594
+
595
595
  This method polls an existing execution until it either:
596
596
  1. Requests human input (paused_by_agent state)
597
597
  2. Reaches a terminal state (completed, failed, cancelled)
598
598
  3. Times out
599
-
599
+
600
600
  Unlike interactive_agent, this method doesn't start an execution or handle
601
601
  the response automatically - it just waits and reports what happened.
602
-
602
+
603
603
  Args:
604
604
  execution_id: The execution identifier for an already started execution
605
605
  poll_interval: How often to check for updates in seconds (default: 2.0)
606
606
  timeout: Maximum wait time in seconds (default: 3600 - 1 hour)
607
-
607
+
608
608
  Returns:
609
609
  AgentInteractionResult containing:
610
610
  - is_terminal: True if execution finished (completed/failed/cancelled)
611
611
  - status: Current execution status string
612
612
  - agent_message: Agent's message if requesting interaction (None if terminal)
613
613
  - execution_result: Final result if terminal state (None if requesting interaction)
614
-
614
+
615
615
  Raises:
616
616
  ValueError: If interval or timeout parameters are invalid
617
617
  TimeoutError: If the execution times out
618
618
  AsteroidAPIError: If API calls fail
619
-
619
+
620
620
  Example:
621
621
  # Start an execution first
622
622
  execution_id = client.execute_agent('agent-id', {'input': 'test'})
623
-
623
+
624
624
  # Wait for interaction or completion
625
625
  result = client.wait_for_agent_interaction(execution_id)
626
-
626
+
627
627
  if result.is_terminal:
628
628
  print(f"Execution finished with status: {result.status}")
629
629
  if result.execution_result:
@@ -640,19 +640,19 @@ class AsteroidClient:
640
640
  raise ValueError("poll_interval must be positive")
641
641
  if timeout <= 0:
642
642
  raise ValueError("timeout must be positive")
643
-
643
+
644
644
  start_time = time.time()
645
-
645
+
646
646
  while True:
647
647
  elapsed_time = time.time() - start_time
648
648
  if elapsed_time >= timeout:
649
649
  raise TimeoutError(f"Wait for interaction on execution {execution_id} timed out after {timeout}s")
650
-
650
+
651
651
  # Get current status
652
652
  status_response = self.get_execution_status(execution_id)
653
653
  current_status = status_response.status
654
654
  status_str = current_status.value.lower()
655
-
655
+
656
656
  # Handle terminal states
657
657
  if current_status == Status.COMPLETED:
658
658
  try:
@@ -668,7 +668,7 @@ class AsteroidClient:
668
668
  time.sleep(poll_interval)
669
669
  continue
670
670
  raise e
671
-
671
+
672
672
  elif current_status in [Status.FAILED, Status.CANCELLED]:
673
673
  try:
674
674
  execution_result = self.get_execution_result(execution_id)
@@ -686,7 +686,7 @@ class AsteroidClient:
686
686
  agent_message=None,
687
687
  execution_result=None
688
688
  )
689
-
689
+
690
690
  # Handle agent interaction request
691
691
  elif current_status == Status.PAUSED_BY_AGENT:
692
692
  # Get the agent's message/request
@@ -697,34 +697,34 @@ class AsteroidClient:
697
697
  agent_message=agent_message,
698
698
  execution_result=None
699
699
  )
700
-
700
+
701
701
  # Wait before next poll for non-terminal, non-interaction states
702
702
  time.sleep(poll_interval)
703
-
703
+
704
704
  def _extract_agent_request_message(self, execution_id: str) -> str:
705
705
  """
706
706
  Extract the agent's request message from recent activities.
707
-
707
+
708
708
  Args:
709
709
  execution_id: The execution identifier
710
-
710
+
711
711
  Returns:
712
712
  The agent's message or a default message if not found
713
713
  """
714
714
  try:
715
715
  activities = self.get_last_n_execution_activities(execution_id, 20)
716
-
716
+
717
717
  # Filter for human input requests
718
718
  human_input_requests = [
719
719
  activity for activity in activities
720
- if (hasattr(activity, 'payload') and
721
- activity.payload and
720
+ if (hasattr(activity, 'payload') and
721
+ activity.payload and
722
722
  getattr(activity.payload, 'activityType', None) == 'action_started')
723
723
  ]
724
-
724
+
725
725
  if human_input_requests:
726
726
  human_input_request = human_input_requests[0]
727
-
727
+
728
728
  # Extract message from payload data with robust error handling
729
729
  try:
730
730
  payload = human_input_request.payload
@@ -735,9 +735,9 @@ class AsteroidClient:
735
735
  return 'Agent is requesting input'
736
736
  except (AttributeError, TypeError) as e:
737
737
  return 'Agent is requesting input (extraction failed)'
738
-
738
+
739
739
  return 'Agent is requesting input'
740
-
740
+
741
741
  except AsteroidAPIError as e:
742
742
  return 'Agent is requesting input (API error)'
743
743
  except Exception as e:
@@ -762,33 +762,6 @@ class AsteroidClient:
762
762
  pass
763
763
  return False
764
764
 
765
- # Utility methods for nicer response formatting
766
- def format_agent_profile(self, profile: AgentProfile) -> str:
767
- """Format an agent profile for nice display."""
768
- credentials_info = f"{[(credential.name, credential.id) for credential in profile.credentials]}" if profile.credentials else "No credentials"
769
- return f"""Agent Profile:
770
- ID: {profile.id}
771
- Name: {profile.name}
772
- Description: {profile.description}
773
- Organization: {profile.organization_id}
774
- Proxy: {profile.proxy_cc.value} ({profile.proxy_type.value})
775
- Captcha Solver: {'Enabled' if profile.captcha_solver_active else 'Disabled'}
776
- Sticky IP: {'Yes' if profile.sticky_ip else 'No'}
777
- Credentials: {credentials_info}
778
- Created: {profile.created_at.strftime('%Y-%m-%d %H:%M:%S')}
779
- Updated: {profile.updated_at.strftime('%Y-%m-%d %H:%M:%S')}"""
780
-
781
- def format_agent_profiles_list(self, profiles: List[AgentProfile]) -> str:
782
- """Format a list of agent profiles for nice display."""
783
- if not profiles:
784
- return "No agent profiles found."
785
-
786
- result = f"Found {len(profiles)} agent profile(s):\n"
787
- for i, profile in enumerate(profiles, 1):
788
- credentials_count = len(profile.credentials) if profile.credentials else 0
789
- result += f" {i}. {profile.name} (ID: {profile.id[:8]}...) - {credentials_count} credentials\n"
790
- return result.rstrip()
791
-
792
765
  # --- V2 ---
793
766
 
794
767
  def get_last_n_execution_activities(self, execution_id: str, n: int) -> List[ExecutionActivity]:
@@ -1122,34 +1095,34 @@ def wait_for_agent_interaction(
1122
1095
  ) -> AgentInteractionResult:
1123
1096
  """
1124
1097
  Wait for an agent interaction request or terminal state.
1125
-
1098
+
1126
1099
  This convenience function provides the same functionality as the AsteroidClient.wait_for_agent_interaction method.
1127
-
1100
+
1128
1101
  Args:
1129
1102
  client: The AsteroidClient instance
1130
1103
  execution_id: The execution identifier for an already started execution
1131
1104
  poll_interval: How often to check for updates in seconds (default: 2.0)
1132
1105
  timeout: Maximum wait time in seconds (default: 3600 - 1 hour)
1133
-
1106
+
1134
1107
  Returns:
1135
1108
  AgentInteractionResult containing:
1136
1109
  - is_terminal: True if execution finished (completed/failed/cancelled)
1137
1110
  - status: Current execution status string
1138
1111
  - agent_message: Agent's message if requesting interaction (None if terminal)
1139
1112
  - execution_result: Final result if terminal state (None if requesting interaction)
1140
-
1113
+
1141
1114
  Raises:
1142
1115
  ValueError: If interval or timeout parameters are invalid
1143
1116
  TimeoutError: If the execution times out
1144
1117
  AsteroidAPIError: If API calls fail
1145
-
1118
+
1146
1119
  Example:
1147
1120
  # Start an execution first
1148
1121
  execution_id = execute_agent(client, 'agent-id', {'input': 'test'})
1149
-
1122
+
1150
1123
  # Wait for interaction or completion
1151
1124
  result = wait_for_agent_interaction(client, execution_id)
1152
-
1125
+
1153
1126
  if result.is_terminal:
1154
1127
  print(f"Execution finished with status: {result.status}")
1155
1128
  if result.execution_result:
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: asteroid-odyssey
3
- Version: 1.3.1
3
+ Version: 1.3.2
4
4
  Summary: A Python SDK for browser automation using Asteroid platform.
5
5
  Author-email: David Mlcoch <founders@asteroid.com>
6
6
  License-Expression: MIT
@@ -1,5 +1,5 @@
1
- asteroid_odyssey/__init__.py,sha256=r3WWW_BsZUiHfBcstmWnJxeeDrmWdy-7uovPEHHfO80,915
2
- asteroid_odyssey/client.py,sha256=lcjZ9YMU2w3q05qw2aOVJr78CCaI_FHlkwlAJixpZrQ,45335
1
+ asteroid_odyssey/__init__.py,sha256=Yf0kbvXjjKVBPQV51JCQmId5-CrOhFriHTMOkZmzG2Q,1241
2
+ asteroid_odyssey/client.py,sha256=Jh3S5rbKTISXROz2TpHFJsfgnK-8kqBlbU9uXOoNepc,43591
3
3
  asteroid_odyssey/agents_v1_gen/__init__.py,sha256=bc-NDFcUy9zBjdMcfRgZtKtMotoyz74VMR9jKeCjgkM,4386
4
4
  asteroid_odyssey/agents_v1_gen/api_client.py,sha256=Fq7Uh5yc9Mwza9NgCE1A0g2zrJ_hl5qQ_WFkACeHxWw,27747
5
5
  asteroid_odyssey/agents_v1_gen/api_response.py,sha256=eMxw1mpmJcoGZ3gs9z6jM4oYoZ10Gjk333s9sKxGv7s,652
@@ -71,7 +71,7 @@ asteroid_odyssey/agents_v2_gen/models/execution_status.py,sha256=SHpsS6IzN42kPdD
71
71
  asteroid_odyssey/agents_v2_gen/models/execution_terminal_payload.py,sha256=hWh7Fuy0fswZZFwXncRwdtlyDD4WGEA-wYYdtOg8-vQ,2935
72
72
  asteroid_odyssey/agents_v2_gen/models/execution_user_messages_add_text_body.py,sha256=BQ9klnV_2-3svbyPFcGC272y7uKanIKtpbwVPXQs6gk,2559
73
73
  asteroid_odyssey/agents_v2_gen/models/versions.py,sha256=54MndkW0A32LnZbTGHEsFnNRrrT112iWNJMgk7-a2eM,736
74
- asteroid_odyssey-1.3.1.dist-info/METADATA,sha256=fjCqNaAB4EAyUb0dhY3OToLWfbQ2h2_LsHuX9ewMvcI,7073
75
- asteroid_odyssey-1.3.1.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
76
- asteroid_odyssey-1.3.1.dist-info/top_level.txt,sha256=h4T6NKscnThJ4Nhzors2NKlJeZzepnM7XvDgsnfi5HA,17
77
- asteroid_odyssey-1.3.1.dist-info/RECORD,,
74
+ asteroid_odyssey-1.3.2.dist-info/METADATA,sha256=IlcNGC5lhxuF0jueSgHeJjbOUPekQQnuphbfMWQYcoU,7073
75
+ asteroid_odyssey-1.3.2.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
76
+ asteroid_odyssey-1.3.2.dist-info/top_level.txt,sha256=h4T6NKscnThJ4Nhzors2NKlJeZzepnM7XvDgsnfi5HA,17
77
+ asteroid_odyssey-1.3.2.dist-info/RECORD,,