minitap-mobile-use 2.7.1__tar.gz → 2.7.2__tar.gz

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.

Potentially problematic release.


This version of minitap-mobile-use might be problematic. Click here for more details.

Files changed (102) hide show
  1. {minitap_mobile_use-2.7.1 → minitap_mobile_use-2.7.2}/PKG-INFO +1 -1
  2. {minitap_mobile_use-2.7.1 → minitap_mobile_use-2.7.2}/minitap/mobile_use/agents/cortex/cortex.py +2 -6
  3. {minitap_mobile_use-2.7.1 → minitap_mobile_use-2.7.2}/minitap/mobile_use/agents/executor/executor.py +2 -6
  4. {minitap_mobile_use-2.7.1 → minitap_mobile_use-2.7.2}/minitap/mobile_use/agents/executor/tool_node.py +31 -6
  5. {minitap_mobile_use-2.7.1 → minitap_mobile_use-2.7.2}/minitap/mobile_use/agents/hopper/hopper.py +2 -6
  6. {minitap_mobile_use-2.7.1 → minitap_mobile_use-2.7.2}/minitap/mobile_use/agents/orchestrator/orchestrator.py +2 -6
  7. {minitap_mobile_use-2.7.1 → minitap_mobile_use-2.7.2}/minitap/mobile_use/agents/outputter/outputter.py +2 -4
  8. {minitap_mobile_use-2.7.1 → minitap_mobile_use-2.7.2}/minitap/mobile_use/agents/planner/planner.py +2 -2
  9. {minitap_mobile_use-2.7.1 → minitap_mobile_use-2.7.2}/minitap/mobile_use/agents/screen_analyzer/screen_analyzer.py +2 -6
  10. {minitap_mobile_use-2.7.1 → minitap_mobile_use-2.7.2}/minitap/mobile_use/config.py +1 -1
  11. {minitap_mobile_use-2.7.1 → minitap_mobile_use-2.7.2}/minitap/mobile_use/graph/graph.py +6 -2
  12. {minitap_mobile_use-2.7.1 → minitap_mobile_use-2.7.2}/minitap/mobile_use/sdk/builders/agent_config_builder.py +16 -9
  13. {minitap_mobile_use-2.7.1 → minitap_mobile_use-2.7.2}/minitap/mobile_use/services/llm.py +0 -2
  14. {minitap_mobile_use-2.7.1 → minitap_mobile_use-2.7.2}/pyproject.toml +1 -1
  15. {minitap_mobile_use-2.7.1 → minitap_mobile_use-2.7.2}/LICENSE +0 -0
  16. {minitap_mobile_use-2.7.1 → minitap_mobile_use-2.7.2}/README.md +0 -0
  17. {minitap_mobile_use-2.7.1 → minitap_mobile_use-2.7.2}/minitap/mobile_use/__init__.py +0 -0
  18. {minitap_mobile_use-2.7.1 → minitap_mobile_use-2.7.2}/minitap/mobile_use/agents/contextor/contextor.py +0 -0
  19. {minitap_mobile_use-2.7.1 → minitap_mobile_use-2.7.2}/minitap/mobile_use/agents/cortex/cortex.md +0 -0
  20. {minitap_mobile_use-2.7.1 → minitap_mobile_use-2.7.2}/minitap/mobile_use/agents/cortex/types.py +0 -0
  21. {minitap_mobile_use-2.7.1 → minitap_mobile_use-2.7.2}/minitap/mobile_use/agents/executor/executor.md +0 -0
  22. {minitap_mobile_use-2.7.1 → minitap_mobile_use-2.7.2}/minitap/mobile_use/agents/executor/utils.py +0 -0
  23. {minitap_mobile_use-2.7.1 → minitap_mobile_use-2.7.2}/minitap/mobile_use/agents/hopper/hopper.md +0 -0
  24. {minitap_mobile_use-2.7.1 → minitap_mobile_use-2.7.2}/minitap/mobile_use/agents/orchestrator/human.md +0 -0
  25. {minitap_mobile_use-2.7.1 → minitap_mobile_use-2.7.2}/minitap/mobile_use/agents/orchestrator/orchestrator.md +0 -0
  26. {minitap_mobile_use-2.7.1 → minitap_mobile_use-2.7.2}/minitap/mobile_use/agents/orchestrator/types.py +0 -0
  27. {minitap_mobile_use-2.7.1 → minitap_mobile_use-2.7.2}/minitap/mobile_use/agents/outputter/human.md +0 -0
  28. {minitap_mobile_use-2.7.1 → minitap_mobile_use-2.7.2}/minitap/mobile_use/agents/outputter/test_outputter.py +0 -0
  29. {minitap_mobile_use-2.7.1 → minitap_mobile_use-2.7.2}/minitap/mobile_use/agents/planner/human.md +0 -0
  30. {minitap_mobile_use-2.7.1 → minitap_mobile_use-2.7.2}/minitap/mobile_use/agents/planner/planner.md +0 -0
  31. {minitap_mobile_use-2.7.1 → minitap_mobile_use-2.7.2}/minitap/mobile_use/agents/planner/types.py +0 -0
  32. {minitap_mobile_use-2.7.1 → minitap_mobile_use-2.7.2}/minitap/mobile_use/agents/planner/utils.py +0 -0
  33. {minitap_mobile_use-2.7.1 → minitap_mobile_use-2.7.2}/minitap/mobile_use/agents/screen_analyzer/human.md +0 -0
  34. {minitap_mobile_use-2.7.1 → minitap_mobile_use-2.7.2}/minitap/mobile_use/agents/summarizer/summarizer.py +0 -0
  35. {minitap_mobile_use-2.7.1 → minitap_mobile_use-2.7.2}/minitap/mobile_use/clients/device_hardware_client.py +0 -0
  36. {minitap_mobile_use-2.7.1 → minitap_mobile_use-2.7.2}/minitap/mobile_use/clients/ios_client.py +0 -0
  37. {minitap_mobile_use-2.7.1 → minitap_mobile_use-2.7.2}/minitap/mobile_use/clients/screen_api_client.py +0 -0
  38. {minitap_mobile_use-2.7.1 → minitap_mobile_use-2.7.2}/minitap/mobile_use/constants.py +0 -0
  39. {minitap_mobile_use-2.7.1 → minitap_mobile_use-2.7.2}/minitap/mobile_use/context.py +0 -0
  40. {minitap_mobile_use-2.7.1 → minitap_mobile_use-2.7.2}/minitap/mobile_use/controllers/__init__.py +0 -0
  41. {minitap_mobile_use-2.7.1 → minitap_mobile_use-2.7.2}/minitap/mobile_use/controllers/mobile_command_controller.py +0 -0
  42. {minitap_mobile_use-2.7.1 → minitap_mobile_use-2.7.2}/minitap/mobile_use/controllers/platform_specific_commands_controller.py +0 -0
  43. {minitap_mobile_use-2.7.1 → minitap_mobile_use-2.7.2}/minitap/mobile_use/controllers/types.py +0 -0
  44. {minitap_mobile_use-2.7.1 → minitap_mobile_use-2.7.2}/minitap/mobile_use/graph/state.py +0 -0
  45. {minitap_mobile_use-2.7.1 → minitap_mobile_use-2.7.2}/minitap/mobile_use/main.py +0 -0
  46. {minitap_mobile_use-2.7.1 → minitap_mobile_use-2.7.2}/minitap/mobile_use/sdk/__init__.py +0 -0
  47. {minitap_mobile_use-2.7.1 → minitap_mobile_use-2.7.2}/minitap/mobile_use/sdk/agent.py +0 -0
  48. {minitap_mobile_use-2.7.1 → minitap_mobile_use-2.7.2}/minitap/mobile_use/sdk/builders/__init__.py +0 -0
  49. {minitap_mobile_use-2.7.1 → minitap_mobile_use-2.7.2}/minitap/mobile_use/sdk/builders/index.py +0 -0
  50. {minitap_mobile_use-2.7.1 → minitap_mobile_use-2.7.2}/minitap/mobile_use/sdk/builders/task_request_builder.py +0 -0
  51. {minitap_mobile_use-2.7.1 → minitap_mobile_use-2.7.2}/minitap/mobile_use/sdk/constants.py +0 -0
  52. {minitap_mobile_use-2.7.1 → minitap_mobile_use-2.7.2}/minitap/mobile_use/sdk/examples/README.md +0 -0
  53. {minitap_mobile_use-2.7.1 → minitap_mobile_use-2.7.2}/minitap/mobile_use/sdk/examples/__init__.py +0 -0
  54. {minitap_mobile_use-2.7.1 → minitap_mobile_use-2.7.2}/minitap/mobile_use/sdk/examples/platform_manual_task_example.py +0 -0
  55. {minitap_mobile_use-2.7.1 → minitap_mobile_use-2.7.2}/minitap/mobile_use/sdk/examples/platform_minimal_example.py +0 -0
  56. {minitap_mobile_use-2.7.1 → minitap_mobile_use-2.7.2}/minitap/mobile_use/sdk/examples/simple_photo_organizer.py +0 -0
  57. {minitap_mobile_use-2.7.1 → minitap_mobile_use-2.7.2}/minitap/mobile_use/sdk/examples/smart_notification_assistant.py +0 -0
  58. {minitap_mobile_use-2.7.1 → minitap_mobile_use-2.7.2}/minitap/mobile_use/sdk/services/platform.py +0 -0
  59. {minitap_mobile_use-2.7.1 → minitap_mobile_use-2.7.2}/minitap/mobile_use/sdk/types/__init__.py +0 -0
  60. {minitap_mobile_use-2.7.1 → minitap_mobile_use-2.7.2}/minitap/mobile_use/sdk/types/agent.py +0 -0
  61. {minitap_mobile_use-2.7.1 → minitap_mobile_use-2.7.2}/minitap/mobile_use/sdk/types/exceptions.py +0 -0
  62. {minitap_mobile_use-2.7.1 → minitap_mobile_use-2.7.2}/minitap/mobile_use/sdk/types/platform.py +0 -0
  63. {minitap_mobile_use-2.7.1 → minitap_mobile_use-2.7.2}/minitap/mobile_use/sdk/types/task.py +0 -0
  64. {minitap_mobile_use-2.7.1 → minitap_mobile_use-2.7.2}/minitap/mobile_use/sdk/utils.py +0 -0
  65. {minitap_mobile_use-2.7.1 → minitap_mobile_use-2.7.2}/minitap/mobile_use/servers/config.py +0 -0
  66. {minitap_mobile_use-2.7.1 → minitap_mobile_use-2.7.2}/minitap/mobile_use/servers/device_hardware_bridge.py +0 -0
  67. {minitap_mobile_use-2.7.1 → minitap_mobile_use-2.7.2}/minitap/mobile_use/servers/device_screen_api.py +0 -0
  68. {minitap_mobile_use-2.7.1 → minitap_mobile_use-2.7.2}/minitap/mobile_use/servers/start_servers.py +0 -0
  69. {minitap_mobile_use-2.7.1 → minitap_mobile_use-2.7.2}/minitap/mobile_use/servers/stop_servers.py +0 -0
  70. {minitap_mobile_use-2.7.1 → minitap_mobile_use-2.7.2}/minitap/mobile_use/servers/utils.py +0 -0
  71. {minitap_mobile_use-2.7.1 → minitap_mobile_use-2.7.2}/minitap/mobile_use/services/accessibility.py +0 -0
  72. {minitap_mobile_use-2.7.1 → minitap_mobile_use-2.7.2}/minitap/mobile_use/tools/index.py +0 -0
  73. {minitap_mobile_use-2.7.1 → minitap_mobile_use-2.7.2}/minitap/mobile_use/tools/mobile/back.py +0 -0
  74. {minitap_mobile_use-2.7.1 → minitap_mobile_use-2.7.2}/minitap/mobile_use/tools/mobile/erase_one_char.py +0 -0
  75. {minitap_mobile_use-2.7.1 → minitap_mobile_use-2.7.2}/minitap/mobile_use/tools/mobile/focus_and_clear_text.py +0 -0
  76. {minitap_mobile_use-2.7.1 → minitap_mobile_use-2.7.2}/minitap/mobile_use/tools/mobile/focus_and_input_text.py +0 -0
  77. {minitap_mobile_use-2.7.1 → minitap_mobile_use-2.7.2}/minitap/mobile_use/tools/mobile/launch_app.py +0 -0
  78. {minitap_mobile_use-2.7.1 → minitap_mobile_use-2.7.2}/minitap/mobile_use/tools/mobile/long_press_on.py +0 -0
  79. {minitap_mobile_use-2.7.1 → minitap_mobile_use-2.7.2}/minitap/mobile_use/tools/mobile/open_link.py +0 -0
  80. {minitap_mobile_use-2.7.1 → minitap_mobile_use-2.7.2}/minitap/mobile_use/tools/mobile/press_key.py +0 -0
  81. {minitap_mobile_use-2.7.1 → minitap_mobile_use-2.7.2}/minitap/mobile_use/tools/mobile/stop_app.py +0 -0
  82. {minitap_mobile_use-2.7.1 → minitap_mobile_use-2.7.2}/minitap/mobile_use/tools/mobile/swipe.py +0 -0
  83. {minitap_mobile_use-2.7.1 → minitap_mobile_use-2.7.2}/minitap/mobile_use/tools/mobile/tap.py +0 -0
  84. {minitap_mobile_use-2.7.1 → minitap_mobile_use-2.7.2}/minitap/mobile_use/tools/mobile/wait_for_delay.py +0 -0
  85. {minitap_mobile_use-2.7.1 → minitap_mobile_use-2.7.2}/minitap/mobile_use/tools/test_utils.py +0 -0
  86. {minitap_mobile_use-2.7.1 → minitap_mobile_use-2.7.2}/minitap/mobile_use/tools/tool_wrapper.py +0 -0
  87. {minitap_mobile_use-2.7.1 → minitap_mobile_use-2.7.2}/minitap/mobile_use/tools/types.py +0 -0
  88. {minitap_mobile_use-2.7.1 → minitap_mobile_use-2.7.2}/minitap/mobile_use/tools/utils.py +0 -0
  89. {minitap_mobile_use-2.7.1 → minitap_mobile_use-2.7.2}/minitap/mobile_use/utils/cli_helpers.py +0 -0
  90. {minitap_mobile_use-2.7.1 → minitap_mobile_use-2.7.2}/minitap/mobile_use/utils/cli_selection.py +0 -0
  91. {minitap_mobile_use-2.7.1 → minitap_mobile_use-2.7.2}/minitap/mobile_use/utils/conversations.py +0 -0
  92. {minitap_mobile_use-2.7.1 → minitap_mobile_use-2.7.2}/minitap/mobile_use/utils/decorators.py +0 -0
  93. {minitap_mobile_use-2.7.1 → minitap_mobile_use-2.7.2}/minitap/mobile_use/utils/errors.py +0 -0
  94. {minitap_mobile_use-2.7.1 → minitap_mobile_use-2.7.2}/minitap/mobile_use/utils/file.py +0 -0
  95. {minitap_mobile_use-2.7.1 → minitap_mobile_use-2.7.2}/minitap/mobile_use/utils/logger.py +0 -0
  96. {minitap_mobile_use-2.7.1 → minitap_mobile_use-2.7.2}/minitap/mobile_use/utils/media.py +0 -0
  97. {minitap_mobile_use-2.7.1 → minitap_mobile_use-2.7.2}/minitap/mobile_use/utils/recorder.py +0 -0
  98. {minitap_mobile_use-2.7.1 → minitap_mobile_use-2.7.2}/minitap/mobile_use/utils/requests_utils.py +0 -0
  99. {minitap_mobile_use-2.7.1 → minitap_mobile_use-2.7.2}/minitap/mobile_use/utils/shell_utils.py +0 -0
  100. {minitap_mobile_use-2.7.1 → minitap_mobile_use-2.7.2}/minitap/mobile_use/utils/test_ui_hierarchy.py +0 -0
  101. {minitap_mobile_use-2.7.1 → minitap_mobile_use-2.7.2}/minitap/mobile_use/utils/time.py +0 -0
  102. {minitap_mobile_use-2.7.1 → minitap_mobile_use-2.7.2}/minitap/mobile_use/utils/ui_hierarchy.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: minitap-mobile-use
3
- Version: 2.7.1
3
+ Version: 2.7.2
4
4
  Summary: AI-powered multi-agent system that automates real Android and iOS devices through low-level control using LangGraph.
5
5
  Author: Pierre-Louis Favreau, Jean-Pierre Lo, Nicolas Dehandschoewercker
6
6
  License: MIT License
@@ -73,12 +73,8 @@ class CortexNode:
73
73
  ctx=self.ctx, name="cortex", use_fallback=True, temperature=1
74
74
  ).with_structured_output(CortexOutput)
75
75
  response: CortexOutput = await with_fallback(
76
- main_call=lambda: invoke_llm_with_timeout_message(
77
- llm.ainvoke(messages), agent_name="Cortex"
78
- ),
79
- fallback_call=lambda: invoke_llm_with_timeout_message(
80
- llm_fallback.ainvoke(messages), agent_name="Cortex (Fallback)"
81
- ),
76
+ main_call=lambda: invoke_llm_with_timeout_message(llm.ainvoke(messages)),
77
+ fallback_call=lambda: invoke_llm_with_timeout_message(llm_fallback.ainvoke(messages)),
82
78
  ) # type: ignore
83
79
 
84
80
  EMPTY_STRING_TOKENS = ["{}", "[]", "null", "", "None"]
@@ -65,12 +65,8 @@ class ExecutorNode:
65
65
  llm = llm.bind_tools(**llm_bind_tools_kwargs)
66
66
  llm_fallback = llm_fallback.bind_tools(**llm_bind_tools_kwargs)
67
67
  response = await with_fallback(
68
- main_call=lambda: invoke_llm_with_timeout_message(
69
- llm.ainvoke(messages), agent_name="Executor"
70
- ),
71
- fallback_call=lambda: invoke_llm_with_timeout_message(
72
- llm_fallback.ainvoke(messages), agent_name="Executor (Fallback)"
73
- ),
68
+ main_call=lambda: invoke_llm_with_timeout_message(llm.ainvoke(messages)),
69
+ fallback_call=lambda: invoke_llm_with_timeout_message(llm_fallback.ainvoke(messages)),
74
70
  )
75
71
  return await state.asanitize_update(
76
72
  ctx=self.ctx,
@@ -1,12 +1,17 @@
1
1
  import asyncio
2
- from typing import Any
3
- from langgraph.types import Command
4
- from pydantic import BaseModel
5
- from typing import override
6
- from langchain_core.runnables import RunnableConfig
7
- from langgraph.store.base import BaseStore
2
+ import copy
3
+ from typing import Any, override
4
+
8
5
  from langchain_core.messages import AnyMessage, ToolCall, ToolMessage
6
+ from langchain_core.runnables import RunnableConfig
9
7
  from langgraph.prebuilt import ToolNode
8
+ from langgraph.store.base import BaseStore
9
+ from langgraph.types import Command
10
+ from pydantic import BaseModel
11
+
12
+ from minitap.mobile_use.utils.logger import get_logger
13
+
14
+ logger = get_logger(__name__)
10
15
 
11
16
 
12
17
  class ExecutorToolNode(ToolNode):
@@ -67,6 +72,26 @@ class ExecutorToolNode(ToolNode):
67
72
  message=f"Unexpected tool output type: {type(output)}",
68
73
  )
69
74
  failed = True
75
+
76
+ call_without_state = copy.deepcopy(call)
77
+ if "args" in call_without_state and "state" in call_without_state["args"]:
78
+ del call_without_state["args"]["state"]
79
+ if failed:
80
+ error_msg = ""
81
+ try:
82
+ if isinstance(output, ToolMessage):
83
+ error_msg = output.content
84
+ elif isinstance(output, Command):
85
+ tool_msg = self._get_tool_message(output)
86
+ error_msg = tool_msg.content
87
+ except Exception:
88
+ error_msg = "Could not extract error details"
89
+
90
+ logger.info(f"❌ Tool call failed: {call_without_state}")
91
+ logger.info(f" Error: {error_msg}")
92
+ else:
93
+ logger.info("✅ Tool call succeeded: " + str(call_without_state))
94
+
70
95
  outputs.append(output)
71
96
  return self._combine_tool_outputs(outputs, input_type) # type: ignore
72
97
 
@@ -37,11 +37,7 @@ async def hopper(
37
37
  ctx=ctx, name="hopper", is_utils=True, use_fallback=True, temperature=0
38
38
  ).with_structured_output(HopperOutput)
39
39
  response: HopperOutput = await with_fallback(
40
- main_call=lambda: invoke_llm_with_timeout_message(
41
- llm.ainvoke(messages), agent_name="Hopper"
42
- ),
43
- fallback_call=lambda: invoke_llm_with_timeout_message(
44
- llm_fallback.ainvoke(messages), agent_name="Hopper (Fallback)"
45
- ),
40
+ main_call=lambda: invoke_llm_with_timeout_message(llm.ainvoke(messages)),
41
+ fallback_call=lambda: invoke_llm_with_timeout_message(llm_fallback.ainvoke(messages)),
46
42
  ) # type: ignore
47
43
  return response
@@ -81,12 +81,8 @@ class OrchestratorNode:
81
81
  ctx=self.ctx, name="orchestrator", use_fallback=True, temperature=1
82
82
  ).with_structured_output(OrchestratorOutput)
83
83
  response: OrchestratorOutput = await with_fallback(
84
- main_call=lambda: invoke_llm_with_timeout_message(
85
- llm.ainvoke(messages), agent_name="Orchestrator"
86
- ),
87
- fallback_call=lambda: invoke_llm_with_timeout_message(
88
- llm_fallback.ainvoke(messages), agent_name="Orchestrator (Fallback)"
89
- ),
84
+ main_call=lambda: invoke_llm_with_timeout_message(llm.ainvoke(messages)),
85
+ fallback_call=lambda: invoke_llm_with_timeout_message(llm_fallback.ainvoke(messages)),
90
86
  ) # type: ignore
91
87
  if response.needs_replaning:
92
88
  thoughts = [response.reason]
@@ -68,11 +68,9 @@ async def outputter(
68
68
  structured_llm_fallback = llm_fallback.with_structured_output(schema)
69
69
 
70
70
  response = await with_fallback(
71
- main_call=lambda: invoke_llm_with_timeout_message(
72
- structured_llm.ainvoke(messages), agent_name="Outputter"
73
- ),
71
+ main_call=lambda: invoke_llm_with_timeout_message(structured_llm.ainvoke(messages)),
74
72
  fallback_call=lambda: invoke_llm_with_timeout_message(
75
- structured_llm_fallback.ainvoke(messages), agent_name="Outputter (Fallback)"
73
+ structured_llm_fallback.ainvoke(messages)
76
74
  ),
77
75
  ) # type: ignore
78
76
  if isinstance(response, BaseModel):
@@ -52,10 +52,10 @@ class PlannerNode:
52
52
  ).with_structured_output(PlannerOutput)
53
53
  response: PlannerOutput = await with_fallback(
54
54
  main_call=lambda: invoke_llm_with_timeout_message(
55
- llm.ainvoke(messages), agent_name="Planner"
55
+ llm.ainvoke(messages),
56
56
  ),
57
57
  fallback_call=lambda: invoke_llm_with_timeout_message(
58
- llm_fallback.ainvoke(messages), agent_name="Planner (Fallback)"
58
+ llm_fallback.ainvoke(messages),
59
59
  ),
60
60
  ) # type: ignore
61
61
  subgoals_plan = [
@@ -101,11 +101,7 @@ async def screen_analyzer(ctx: MobileUseContext, screenshot_base64: str, prompt:
101
101
  llm_fallback = get_llm(ctx=ctx, name="screen_analyzer", use_fallback=True, temperature=0)
102
102
 
103
103
  response = await with_fallback(
104
- main_call=lambda: invoke_llm_with_timeout_message(
105
- llm.ainvoke(messages), agent_name="ScreenAnalyzer"
106
- ),
107
- fallback_call=lambda: invoke_llm_with_timeout_message(
108
- llm_fallback.ainvoke(messages), agent_name="ScreenAnalyzer (Fallback)"
109
- ),
104
+ main_call=lambda: invoke_llm_with_timeout_message(llm.ainvoke(messages)),
105
+ fallback_call=lambda: invoke_llm_with_timeout_message(llm_fallback.ainvoke(messages)),
110
106
  )
111
107
  return response.content # type: ignore
@@ -86,7 +86,7 @@ def record_events(output_path: Path | None, events: list[str] | BaseModel | Any)
86
86
  else:
87
87
  events_content = json.dumps(events, indent=2)
88
88
 
89
- with open(output_path, "w") as f:
89
+ with open(output_path, "w", encoding="utf-8") as f:
90
90
  f.write(events_content)
91
91
 
92
92
 
@@ -96,10 +96,14 @@ def post_executor_gate(
96
96
  if isinstance(last_message, AIMessage):
97
97
  tool_calls = getattr(last_message, "tool_calls", None)
98
98
  if tool_calls and len(tool_calls) > 0:
99
- logger.info("🔨👁️ Found tool calls: " + str(tool_calls))
99
+ logger.info("[executor] Executing " + str(len(tool_calls)) + " tool calls:")
100
+ for tool_call in tool_calls:
101
+ logger.info("-------------")
102
+ logger.info("[executor] - " + str(tool_call) + "\n")
103
+ logger.info("-------------")
100
104
  return "invoke_tools"
101
105
  else:
102
- logger.info("🔨❌ No tool calls found")
106
+ logger.info("[executor] No tool calls found")
103
107
  return "skip"
104
108
 
105
109
 
@@ -46,7 +46,7 @@ class AgentConfigBuilder:
46
46
  self._servers: ServerConfig = get_default_servers()
47
47
  self._graph_config_callbacks: Callbacks = None
48
48
 
49
- def add_profile(self, profile: AgentProfile) -> "AgentConfigBuilder":
49
+ def add_profile(self, profile: AgentProfile, validate: bool = True) -> "AgentConfigBuilder":
50
50
  """
51
51
  Add an agent profile to the mobile-use agent.
52
52
 
@@ -54,10 +54,15 @@ class AgentConfigBuilder:
54
54
  profile: The agent profile to add
55
55
  """
56
56
  self._agent_profiles[profile.name] = profile
57
- profile.llm_config.validate_providers()
57
+ if validate:
58
+ profile.llm_config.validate_providers()
58
59
  return self
59
60
 
60
- def add_profiles(self, profiles: list[AgentProfile]) -> "AgentConfigBuilder":
61
+ def add_profiles(
62
+ self,
63
+ profiles: list[AgentProfile],
64
+ validate: bool = True,
65
+ ) -> "AgentConfigBuilder":
61
66
  """
62
67
  Add multiple agent profiles to the mobile-use agent.
63
68
 
@@ -65,8 +70,7 @@ class AgentConfigBuilder:
65
70
  profiles: List of agent profiles to add
66
71
  """
67
72
  for profile in profiles:
68
- self.add_profile(profile=profile)
69
- profile.llm_config.validate_providers()
73
+ self.add_profile(profile=profile, validate=validate)
70
74
  return self
71
75
 
72
76
  def with_default_profile(self, profile: str | AgentProfile) -> "AgentConfigBuilder":
@@ -162,7 +166,7 @@ class AgentConfigBuilder:
162
166
  self._graph_config_callbacks = callbacks
163
167
  return self
164
168
 
165
- def build(self) -> AgentConfig:
169
+ def build(self, validate_profiles: bool = True) -> AgentConfig:
166
170
  """
167
171
  Build the mobile-use AgentConfig object.
168
172
 
@@ -185,14 +189,17 @@ class AgentConfigBuilder:
185
189
  elif isinstance(self._default_profile, AgentProfile):
186
190
  default_profile = self._default_profile
187
191
  if default_profile.name not in self._agent_profiles:
188
- self.add_profile(default_profile)
192
+ self.add_profile(default_profile, validate=validate_profiles)
189
193
  elif nb_profiles <= 0:
190
- llm_config = get_default_minitap_llm_config() or get_default_llm_config()
194
+ llm_config = (
195
+ get_default_minitap_llm_config(validate=validate_profiles)
196
+ or get_default_llm_config()
197
+ )
191
198
  default_profile = AgentProfile(
192
199
  name=DEFAULT_PROFILE_NAME,
193
200
  llm_config=llm_config,
194
201
  )
195
- self.add_profile(default_profile)
202
+ self.add_profile(default_profile, validate=validate_profiles)
196
203
  elif nb_profiles == 1:
197
204
  # Select the only one available
198
205
  default_profile = next(iter(self._agent_profiles.values()))
@@ -28,7 +28,6 @@ user_messages_logger = get_logger(__name__)
28
28
 
29
29
  async def invoke_llm_with_timeout_message[T](
30
30
  llm_call: Coroutine[Any, Any, T],
31
- agent_name: str,
32
31
  timeout_seconds: int = 10,
33
32
  ) -> T:
34
33
  """
@@ -36,7 +35,6 @@ async def invoke_llm_with_timeout_message[T](
36
35
 
37
36
  Args:
38
37
  llm_call: The coroutine of the LLM call to execute.
39
- agent_name: The name of the agent making the call (for the message).
40
38
  timeout_seconds: The delay in seconds before displaying the message.
41
39
 
42
40
  Returns:
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "minitap-mobile-use"
3
- version = "2.7.1"
3
+ version = "2.7.2"
4
4
  description = "AI-powered multi-agent system that automates real Android and iOS devices through low-level control using LangGraph."
5
5
  readme = "README.md"
6
6
  license = { file = "LICENSE" }