autobyteus 1.1.3__py3-none-any.whl → 1.1.5__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.
Files changed (284) hide show
  1. autobyteus/agent/agent.py +1 -1
  2. autobyteus/agent/bootstrap_steps/system_prompt_processing_step.py +4 -2
  3. autobyteus/agent/context/__init__.py +4 -2
  4. autobyteus/agent/context/agent_config.py +35 -8
  5. autobyteus/agent/context/agent_context_registry.py +73 -0
  6. autobyteus/agent/events/notifiers.py +4 -0
  7. autobyteus/agent/events/worker_event_dispatcher.py +1 -2
  8. autobyteus/agent/handlers/inter_agent_message_event_handler.py +8 -3
  9. autobyteus/agent/handlers/llm_complete_response_received_event_handler.py +19 -19
  10. autobyteus/agent/handlers/llm_user_message_ready_event_handler.py +2 -2
  11. autobyteus/agent/handlers/tool_result_event_handler.py +48 -20
  12. autobyteus/agent/handlers/user_input_message_event_handler.py +16 -1
  13. autobyteus/agent/input_processor/__init__.py +1 -7
  14. autobyteus/agent/message/context_file_type.py +6 -0
  15. autobyteus/agent/message/send_message_to.py +74 -99
  16. autobyteus/agent/phases/discover.py +2 -1
  17. autobyteus/agent/runtime/agent_runtime.py +10 -2
  18. autobyteus/agent/runtime/agent_worker.py +1 -0
  19. autobyteus/agent/sender_type.py +15 -0
  20. autobyteus/agent/streaming/agent_event_stream.py +6 -0
  21. autobyteus/agent/streaming/stream_event_payloads.py +12 -0
  22. autobyteus/agent/streaming/stream_events.py +3 -0
  23. autobyteus/agent/system_prompt_processor/tool_manifest_injector_processor.py +7 -4
  24. autobyteus/agent/tool_execution_result_processor/__init__.py +9 -0
  25. autobyteus/agent/tool_execution_result_processor/base_processor.py +46 -0
  26. autobyteus/agent/tool_execution_result_processor/processor_definition.py +36 -0
  27. autobyteus/agent/tool_execution_result_processor/processor_meta.py +36 -0
  28. autobyteus/agent/tool_execution_result_processor/processor_registry.py +70 -0
  29. autobyteus/agent/workspace/base_workspace.py +17 -2
  30. autobyteus/agent_team/__init__.py +1 -0
  31. autobyteus/agent_team/agent_team.py +93 -0
  32. autobyteus/agent_team/agent_team_builder.py +184 -0
  33. autobyteus/agent_team/base_agent_team.py +86 -0
  34. autobyteus/agent_team/bootstrap_steps/__init__.py +24 -0
  35. autobyteus/agent_team/bootstrap_steps/agent_configuration_preparation_step.py +73 -0
  36. autobyteus/agent_team/bootstrap_steps/agent_team_bootstrapper.py +54 -0
  37. autobyteus/agent_team/bootstrap_steps/agent_team_runtime_queue_initialization_step.py +25 -0
  38. autobyteus/agent_team/bootstrap_steps/base_agent_team_bootstrap_step.py +23 -0
  39. autobyteus/agent_team/bootstrap_steps/coordinator_initialization_step.py +41 -0
  40. autobyteus/agent_team/bootstrap_steps/coordinator_prompt_preparation_step.py +85 -0
  41. autobyteus/agent_team/bootstrap_steps/task_notifier_initialization_step.py +51 -0
  42. autobyteus/agent_team/bootstrap_steps/team_context_initialization_step.py +45 -0
  43. autobyteus/agent_team/context/__init__.py +17 -0
  44. autobyteus/agent_team/context/agent_team_config.py +33 -0
  45. autobyteus/agent_team/context/agent_team_context.py +61 -0
  46. autobyteus/agent_team/context/agent_team_runtime_state.py +56 -0
  47. autobyteus/agent_team/context/team_manager.py +147 -0
  48. autobyteus/agent_team/context/team_node_config.py +76 -0
  49. autobyteus/agent_team/events/__init__.py +29 -0
  50. autobyteus/agent_team/events/agent_team_event_dispatcher.py +39 -0
  51. autobyteus/agent_team/events/agent_team_events.py +53 -0
  52. autobyteus/agent_team/events/agent_team_input_event_queue_manager.py +21 -0
  53. autobyteus/agent_team/exceptions.py +8 -0
  54. autobyteus/agent_team/factory/__init__.py +9 -0
  55. autobyteus/agent_team/factory/agent_team_factory.py +99 -0
  56. autobyteus/agent_team/handlers/__init__.py +19 -0
  57. autobyteus/agent_team/handlers/agent_team_event_handler_registry.py +23 -0
  58. autobyteus/agent_team/handlers/base_agent_team_event_handler.py +16 -0
  59. autobyteus/agent_team/handlers/inter_agent_message_request_event_handler.py +61 -0
  60. autobyteus/agent_team/handlers/lifecycle_agent_team_event_handler.py +27 -0
  61. autobyteus/agent_team/handlers/process_user_message_event_handler.py +46 -0
  62. autobyteus/agent_team/handlers/tool_approval_team_event_handler.py +48 -0
  63. autobyteus/agent_team/phases/__init__.py +11 -0
  64. autobyteus/agent_team/phases/agent_team_operational_phase.py +19 -0
  65. autobyteus/agent_team/phases/agent_team_phase_manager.py +48 -0
  66. autobyteus/agent_team/runtime/__init__.py +13 -0
  67. autobyteus/agent_team/runtime/agent_team_runtime.py +82 -0
  68. autobyteus/agent_team/runtime/agent_team_worker.py +117 -0
  69. autobyteus/agent_team/shutdown_steps/__init__.py +17 -0
  70. autobyteus/agent_team/shutdown_steps/agent_team_shutdown_orchestrator.py +35 -0
  71. autobyteus/agent_team/shutdown_steps/agent_team_shutdown_step.py +42 -0
  72. autobyteus/agent_team/shutdown_steps/base_agent_team_shutdown_step.py +16 -0
  73. autobyteus/agent_team/shutdown_steps/bridge_cleanup_step.py +28 -0
  74. autobyteus/agent_team/shutdown_steps/sub_team_shutdown_step.py +41 -0
  75. autobyteus/agent_team/streaming/__init__.py +26 -0
  76. autobyteus/agent_team/streaming/agent_event_bridge.py +48 -0
  77. autobyteus/agent_team/streaming/agent_event_multiplexer.py +70 -0
  78. autobyteus/agent_team/streaming/agent_team_event_notifier.py +64 -0
  79. autobyteus/agent_team/streaming/agent_team_event_stream.py +33 -0
  80. autobyteus/agent_team/streaming/agent_team_stream_event_payloads.py +32 -0
  81. autobyteus/agent_team/streaming/agent_team_stream_events.py +56 -0
  82. autobyteus/agent_team/streaming/team_event_bridge.py +50 -0
  83. autobyteus/agent_team/task_notification/__init__.py +11 -0
  84. autobyteus/agent_team/task_notification/system_event_driven_agent_task_notifier.py +164 -0
  85. autobyteus/agent_team/task_notification/task_notification_mode.py +24 -0
  86. autobyteus/agent_team/utils/__init__.py +9 -0
  87. autobyteus/agent_team/utils/wait_for_idle.py +46 -0
  88. autobyteus/cli/__init__.py +1 -1
  89. autobyteus/cli/agent_team_tui/__init__.py +4 -0
  90. autobyteus/cli/agent_team_tui/app.py +210 -0
  91. autobyteus/cli/agent_team_tui/state.py +180 -0
  92. autobyteus/cli/agent_team_tui/widgets/__init__.py +6 -0
  93. autobyteus/cli/agent_team_tui/widgets/agent_list_sidebar.py +149 -0
  94. autobyteus/cli/agent_team_tui/widgets/focus_pane.py +320 -0
  95. autobyteus/cli/agent_team_tui/widgets/logo.py +20 -0
  96. autobyteus/cli/agent_team_tui/widgets/renderables.py +77 -0
  97. autobyteus/cli/agent_team_tui/widgets/shared.py +60 -0
  98. autobyteus/cli/agent_team_tui/widgets/status_bar.py +14 -0
  99. autobyteus/cli/agent_team_tui/widgets/task_board_panel.py +82 -0
  100. autobyteus/cli/cli_display.py +1 -1
  101. autobyteus/cli/workflow_tui/__init__.py +4 -0
  102. autobyteus/cli/workflow_tui/app.py +210 -0
  103. autobyteus/cli/workflow_tui/state.py +189 -0
  104. autobyteus/cli/workflow_tui/widgets/__init__.py +6 -0
  105. autobyteus/cli/workflow_tui/widgets/agent_list_sidebar.py +149 -0
  106. autobyteus/cli/workflow_tui/widgets/focus_pane.py +335 -0
  107. autobyteus/cli/workflow_tui/widgets/logo.py +27 -0
  108. autobyteus/cli/workflow_tui/widgets/renderables.py +70 -0
  109. autobyteus/cli/workflow_tui/widgets/shared.py +51 -0
  110. autobyteus/cli/workflow_tui/widgets/status_bar.py +14 -0
  111. autobyteus/events/event_types.py +8 -0
  112. autobyteus/llm/api/autobyteus_llm.py +11 -12
  113. autobyteus/llm/api/lmstudio_llm.py +34 -0
  114. autobyteus/llm/api/ollama_llm.py +8 -13
  115. autobyteus/llm/api/openai_compatible_llm.py +20 -3
  116. autobyteus/llm/autobyteus_provider.py +73 -46
  117. autobyteus/llm/llm_factory.py +103 -139
  118. autobyteus/llm/lmstudio_provider.py +104 -0
  119. autobyteus/llm/models.py +83 -53
  120. autobyteus/llm/ollama_provider.py +69 -61
  121. autobyteus/llm/ollama_provider_resolver.py +1 -0
  122. autobyteus/llm/providers.py +13 -12
  123. autobyteus/llm/runtimes.py +11 -0
  124. autobyteus/llm/token_counter/token_counter_factory.py +2 -0
  125. autobyteus/task_management/__init__.py +43 -0
  126. autobyteus/task_management/base_task_board.py +68 -0
  127. autobyteus/task_management/converters/__init__.py +11 -0
  128. autobyteus/task_management/converters/task_board_converter.py +64 -0
  129. autobyteus/task_management/converters/task_plan_converter.py +48 -0
  130. autobyteus/task_management/deliverable.py +16 -0
  131. autobyteus/task_management/deliverables/__init__.py +8 -0
  132. autobyteus/task_management/deliverables/file_deliverable.py +15 -0
  133. autobyteus/task_management/events.py +27 -0
  134. autobyteus/task_management/in_memory_task_board.py +126 -0
  135. autobyteus/task_management/schemas/__init__.py +15 -0
  136. autobyteus/task_management/schemas/deliverable_schema.py +13 -0
  137. autobyteus/task_management/schemas/plan_definition.py +35 -0
  138. autobyteus/task_management/schemas/task_status_report.py +27 -0
  139. autobyteus/task_management/task_plan.py +110 -0
  140. autobyteus/task_management/tools/__init__.py +14 -0
  141. autobyteus/task_management/tools/get_task_board_status.py +68 -0
  142. autobyteus/task_management/tools/publish_task_plan.py +113 -0
  143. autobyteus/task_management/tools/update_task_status.py +135 -0
  144. autobyteus/tools/__init__.py +2 -0
  145. autobyteus/tools/ask_user_input.py +2 -1
  146. autobyteus/tools/bash/bash_executor.py +61 -15
  147. autobyteus/tools/browser/session_aware/browser_session_aware_navigate_to.py +2 -0
  148. autobyteus/tools/browser/session_aware/browser_session_aware_web_element_trigger.py +3 -0
  149. autobyteus/tools/browser/session_aware/browser_session_aware_webpage_reader.py +3 -0
  150. autobyteus/tools/browser/session_aware/browser_session_aware_webpage_screenshot_taker.py +3 -0
  151. autobyteus/tools/browser/standalone/google_search_ui.py +2 -0
  152. autobyteus/tools/browser/standalone/navigate_to.py +2 -0
  153. autobyteus/tools/browser/standalone/web_page_pdf_generator.py +3 -0
  154. autobyteus/tools/browser/standalone/webpage_image_downloader.py +3 -0
  155. autobyteus/tools/browser/standalone/webpage_reader.py +2 -0
  156. autobyteus/tools/browser/standalone/webpage_screenshot_taker.py +3 -0
  157. autobyteus/tools/file/file_reader.py +36 -9
  158. autobyteus/tools/file/file_writer.py +37 -9
  159. autobyteus/tools/functional_tool.py +5 -4
  160. autobyteus/tools/image_downloader.py +2 -0
  161. autobyteus/tools/mcp/config_service.py +63 -58
  162. autobyteus/tools/mcp/server/http_managed_mcp_server.py +14 -2
  163. autobyteus/tools/mcp/server/stdio_managed_mcp_server.py +14 -2
  164. autobyteus/tools/mcp/server_instance_manager.py +30 -4
  165. autobyteus/tools/mcp/tool_registrar.py +106 -51
  166. autobyteus/tools/parameter_schema.py +17 -11
  167. autobyteus/tools/pdf_downloader.py +2 -1
  168. autobyteus/tools/registry/tool_definition.py +36 -37
  169. autobyteus/tools/registry/tool_registry.py +50 -2
  170. autobyteus/tools/timer.py +2 -0
  171. autobyteus/tools/tool_category.py +15 -4
  172. autobyteus/tools/tool_meta.py +6 -1
  173. autobyteus/tools/tool_origin.py +10 -0
  174. autobyteus/tools/usage/formatters/default_json_example_formatter.py +78 -3
  175. autobyteus/tools/usage/formatters/default_xml_example_formatter.py +23 -3
  176. autobyteus/tools/usage/formatters/gemini_json_example_formatter.py +6 -0
  177. autobyteus/tools/usage/formatters/google_json_example_formatter.py +7 -0
  178. autobyteus/tools/usage/formatters/openai_json_example_formatter.py +6 -4
  179. autobyteus/tools/usage/parsers/gemini_json_tool_usage_parser.py +23 -7
  180. autobyteus/tools/usage/parsers/provider_aware_tool_usage_parser.py +14 -25
  181. autobyteus/tools/usage/providers/__init__.py +2 -12
  182. autobyteus/tools/usage/providers/tool_manifest_provider.py +36 -29
  183. autobyteus/tools/usage/registries/__init__.py +7 -12
  184. autobyteus/tools/usage/registries/tool_formatter_pair.py +15 -0
  185. autobyteus/tools/usage/registries/tool_formatting_registry.py +58 -0
  186. autobyteus/tools/usage/registries/tool_usage_parser_registry.py +55 -0
  187. autobyteus/workflow/agentic_workflow.py +93 -0
  188. autobyteus/{agent/workflow → workflow}/base_agentic_workflow.py +19 -27
  189. autobyteus/workflow/bootstrap_steps/__init__.py +20 -0
  190. autobyteus/workflow/bootstrap_steps/agent_tool_injection_step.py +34 -0
  191. autobyteus/workflow/bootstrap_steps/base_workflow_bootstrap_step.py +23 -0
  192. autobyteus/workflow/bootstrap_steps/coordinator_initialization_step.py +41 -0
  193. autobyteus/workflow/bootstrap_steps/coordinator_prompt_preparation_step.py +108 -0
  194. autobyteus/workflow/bootstrap_steps/workflow_bootstrapper.py +50 -0
  195. autobyteus/workflow/bootstrap_steps/workflow_runtime_queue_initialization_step.py +25 -0
  196. autobyteus/workflow/context/__init__.py +17 -0
  197. autobyteus/workflow/context/team_manager.py +147 -0
  198. autobyteus/workflow/context/workflow_config.py +30 -0
  199. autobyteus/workflow/context/workflow_context.py +61 -0
  200. autobyteus/workflow/context/workflow_node_config.py +76 -0
  201. autobyteus/workflow/context/workflow_runtime_state.py +53 -0
  202. autobyteus/workflow/events/__init__.py +29 -0
  203. autobyteus/workflow/events/workflow_event_dispatcher.py +39 -0
  204. autobyteus/workflow/events/workflow_events.py +53 -0
  205. autobyteus/workflow/events/workflow_input_event_queue_manager.py +21 -0
  206. autobyteus/workflow/exceptions.py +8 -0
  207. autobyteus/workflow/factory/__init__.py +9 -0
  208. autobyteus/workflow/factory/workflow_factory.py +99 -0
  209. autobyteus/workflow/handlers/__init__.py +19 -0
  210. autobyteus/workflow/handlers/base_workflow_event_handler.py +16 -0
  211. autobyteus/workflow/handlers/inter_agent_message_request_event_handler.py +61 -0
  212. autobyteus/workflow/handlers/lifecycle_workflow_event_handler.py +27 -0
  213. autobyteus/workflow/handlers/process_user_message_event_handler.py +46 -0
  214. autobyteus/workflow/handlers/tool_approval_workflow_event_handler.py +39 -0
  215. autobyteus/workflow/handlers/workflow_event_handler_registry.py +23 -0
  216. autobyteus/workflow/phases/__init__.py +11 -0
  217. autobyteus/workflow/phases/workflow_operational_phase.py +19 -0
  218. autobyteus/workflow/phases/workflow_phase_manager.py +48 -0
  219. autobyteus/workflow/runtime/__init__.py +13 -0
  220. autobyteus/workflow/runtime/workflow_runtime.py +82 -0
  221. autobyteus/workflow/runtime/workflow_worker.py +117 -0
  222. autobyteus/workflow/shutdown_steps/__init__.py +17 -0
  223. autobyteus/workflow/shutdown_steps/agent_team_shutdown_step.py +42 -0
  224. autobyteus/workflow/shutdown_steps/base_workflow_shutdown_step.py +16 -0
  225. autobyteus/workflow/shutdown_steps/bridge_cleanup_step.py +28 -0
  226. autobyteus/workflow/shutdown_steps/sub_workflow_shutdown_step.py +41 -0
  227. autobyteus/workflow/shutdown_steps/workflow_shutdown_orchestrator.py +35 -0
  228. autobyteus/workflow/streaming/__init__.py +26 -0
  229. autobyteus/workflow/streaming/agent_event_bridge.py +48 -0
  230. autobyteus/workflow/streaming/agent_event_multiplexer.py +70 -0
  231. autobyteus/workflow/streaming/workflow_event_bridge.py +50 -0
  232. autobyteus/workflow/streaming/workflow_event_notifier.py +83 -0
  233. autobyteus/workflow/streaming/workflow_event_stream.py +33 -0
  234. autobyteus/workflow/streaming/workflow_stream_event_payloads.py +28 -0
  235. autobyteus/workflow/streaming/workflow_stream_events.py +45 -0
  236. autobyteus/workflow/utils/__init__.py +9 -0
  237. autobyteus/workflow/utils/wait_for_idle.py +46 -0
  238. autobyteus/workflow/workflow_builder.py +151 -0
  239. {autobyteus-1.1.3.dist-info → autobyteus-1.1.5.dist-info}/METADATA +16 -14
  240. autobyteus-1.1.5.dist-info/RECORD +455 -0
  241. {autobyteus-1.1.3.dist-info → autobyteus-1.1.5.dist-info}/top_level.txt +1 -0
  242. examples/__init__.py +1 -0
  243. examples/agent_team/__init__.py +1 -0
  244. examples/discover_phase_transitions.py +104 -0
  245. examples/run_browser_agent.py +262 -0
  246. examples/run_google_slides_agent.py +287 -0
  247. examples/run_mcp_browser_client.py +174 -0
  248. examples/run_mcp_google_slides_client.py +270 -0
  249. examples/run_mcp_list_tools.py +189 -0
  250. examples/run_poem_writer.py +284 -0
  251. examples/run_sqlite_agent.py +295 -0
  252. autobyteus/agent/context/agent_phase_manager.py +0 -264
  253. autobyteus/agent/context/phases.py +0 -49
  254. autobyteus/agent/group/__init__.py +0 -0
  255. autobyteus/agent/group/agent_group.py +0 -164
  256. autobyteus/agent/group/agent_group_context.py +0 -81
  257. autobyteus/agent/input_processor/content_prefixing_input_processor.py +0 -41
  258. autobyteus/agent/input_processor/metadata_appending_input_processor.py +0 -34
  259. autobyteus/agent/input_processor/passthrough_input_processor.py +0 -33
  260. autobyteus/agent/workflow/__init__.py +0 -11
  261. autobyteus/agent/workflow/agentic_workflow.py +0 -89
  262. autobyteus/tools/mcp/call_handlers/__init__.py +0 -16
  263. autobyteus/tools/mcp/call_handlers/base_handler.py +0 -40
  264. autobyteus/tools/mcp/call_handlers/stdio_handler.py +0 -76
  265. autobyteus/tools/mcp/call_handlers/streamable_http_handler.py +0 -55
  266. autobyteus/tools/mcp/registrar.py +0 -202
  267. autobyteus/tools/usage/providers/json_example_provider.py +0 -32
  268. autobyteus/tools/usage/providers/json_schema_provider.py +0 -35
  269. autobyteus/tools/usage/providers/json_tool_usage_parser_provider.py +0 -28
  270. autobyteus/tools/usage/providers/xml_example_provider.py +0 -28
  271. autobyteus/tools/usage/providers/xml_schema_provider.py +0 -29
  272. autobyteus/tools/usage/providers/xml_tool_usage_parser_provider.py +0 -26
  273. autobyteus/tools/usage/registries/json_example_formatter_registry.py +0 -51
  274. autobyteus/tools/usage/registries/json_schema_formatter_registry.py +0 -51
  275. autobyteus/tools/usage/registries/json_tool_usage_parser_registry.py +0 -42
  276. autobyteus/tools/usage/registries/xml_example_formatter_registry.py +0 -30
  277. autobyteus/tools/usage/registries/xml_schema_formatter_registry.py +0 -33
  278. autobyteus/tools/usage/registries/xml_tool_usage_parser_registry.py +0 -30
  279. autobyteus/workflow/simple_task.py +0 -98
  280. autobyteus/workflow/task.py +0 -147
  281. autobyteus/workflow/workflow.py +0 -49
  282. autobyteus-1.1.3.dist-info/RECORD +0 -312
  283. {autobyteus-1.1.3.dist-info → autobyteus-1.1.5.dist-info}/WHEEL +0 -0
  284. {autobyteus-1.1.3.dist-info → autobyteus-1.1.5.dist-info}/licenses/LICENSE +0 -0
@@ -14,8 +14,6 @@ class ParameterType(str, Enum):
14
14
  FLOAT = "float"
15
15
  BOOLEAN = "boolean"
16
16
  ENUM = "enum"
17
- # FILE_PATH = "file_path" # REMOVED
18
- # DIRECTORY_PATH = "directory_path" # REMOVED
19
17
  OBJECT = "object"
20
18
  ARRAY = "array"
21
19
 
@@ -23,11 +21,8 @@ class ParameterType(str, Enum):
23
21
  """Maps parameter type to JSON schema type."""
24
22
  if self == ParameterType.FLOAT:
25
23
  return "number"
26
- # REMOVED: FILE_PATH and DIRECTORY_PATH handling, ENUM still maps to string
27
24
  if self == ParameterType.ENUM:
28
25
  return "string"
29
- # For OBJECT and ARRAY, their value is already the correct JSON schema type
30
- # STRING, INTEGER, BOOLEAN also map directly to their values.
31
26
  if self in [ParameterType.OBJECT, ParameterType.ARRAY, ParameterType.STRING, ParameterType.INTEGER, ParameterType.BOOLEAN]:
32
27
  return self.value
33
28
  return self.value # Fallback, should be covered by above
@@ -46,8 +41,9 @@ class ParameterDefinition:
46
41
  min_value: Optional[Union[int, float]] = None
47
42
  max_value: Optional[Union[int, float]] = None
48
43
  pattern: Optional[str] = None
49
- array_item_schema: Optional[Dict[str, Any]] = None
50
-
44
+ array_item_schema: Optional[Dict[str, Any]] = None
45
+ object_schema: Optional[Dict[str, Any]] = None
46
+
51
47
  def __post_init__(self):
52
48
  if not self.name or not isinstance(self.name, str):
53
49
  raise ValueError("ParameterDefinition name must be a non-empty string")
@@ -64,6 +60,9 @@ class ParameterDefinition:
64
60
  if self.param_type != ParameterType.ARRAY and self.array_item_schema is not None:
65
61
  raise ValueError(f"ParameterDefinition '{self.name}': array_item_schema should only be provided if param_type is ARRAY.")
66
62
 
63
+ if self.param_type != ParameterType.OBJECT and self.object_schema is not None:
64
+ raise ValueError(f"ParameterDefinition '{self.name}': object_schema should only be provided if param_type is OBJECT.")
65
+
67
66
  if self.required and self.default_value is not None:
68
67
  logger.debug(f"ParameterDefinition '{self.name}' is marked as required but has a default value. This is acceptable.")
69
68
 
@@ -103,8 +102,6 @@ class ParameterDefinition:
103
102
  if not isinstance(value, str) or value not in (self.enum_values or []):
104
103
  return False
105
104
 
106
- # REMOVED: Specific validation for FILE_PATH, DIRECTORY_PATH (they are now STRING)
107
-
108
105
  elif self.param_type == ParameterType.OBJECT:
109
106
  if not isinstance(value, dict):
110
107
  return False
@@ -129,9 +126,18 @@ class ParameterDefinition:
129
126
  }
130
127
  if self.param_type == ParameterType.ARRAY and self.array_item_schema is not None:
131
128
  data["array_item_schema"] = self.array_item_schema
129
+ if self.param_type == ParameterType.OBJECT and self.object_schema is not None:
130
+ data["object_schema"] = self.object_schema
132
131
  return data
133
132
 
134
133
  def to_json_schema_property_dict(self) -> Dict[str, Any]:
134
+ if self.param_type == ParameterType.OBJECT and self.object_schema:
135
+ # If a detailed object schema is provided, use it directly.
136
+ # We add the description at the top level for clarity.
137
+ schema = self.object_schema.copy()
138
+ schema["description"] = self.description
139
+ return schema
140
+
135
141
  prop_dict: Dict[str, Any] = {
136
142
  "type": self.param_type.to_json_schema_type(),
137
143
  "description": self.description,
@@ -150,7 +156,6 @@ class ParameterDefinition:
150
156
  if self.param_type in [ParameterType.INTEGER, ParameterType.FLOAT]:
151
157
  prop_dict["maximum"] = self.max_value
152
158
 
153
- # REMOVED: Pattern check specific to FILE_PATH/DIRECTORY_PATH as they are now STRING
154
159
  if self.pattern and self.param_type == ParameterType.STRING:
155
160
  prop_dict["pattern"] = self.pattern
156
161
 
@@ -255,7 +260,8 @@ class ParameterSchema:
255
260
  min_value=param_data.get("min_value"),
256
261
  max_value=param_data.get("max_value"),
257
262
  pattern=param_data.get("pattern"),
258
- array_item_schema=param_data.get("array_item_schema")
263
+ array_item_schema=param_data.get("array_item_schema"),
264
+ object_schema=param_data.get("object_schema")
259
265
  )
260
266
  schema.add_parameter(param)
261
267
 
@@ -7,6 +7,7 @@ from datetime import datetime
7
7
  from typing import TYPE_CHECKING, Optional
8
8
 
9
9
  from autobyteus.tools import tool
10
+ from autobyteus.tools.tool_category import ToolCategory
10
11
  from autobyteus.utils.file_utils import get_default_download_folder
11
12
 
12
13
  if TYPE_CHECKING:
@@ -14,7 +15,7 @@ if TYPE_CHECKING:
14
15
 
15
16
  logger = logging.getLogger(__name__)
16
17
 
17
- @tool(name="PDFDownloader")
18
+ @tool(name="PDFDownloader", category=ToolCategory.WEB)
18
19
  async def pdf_downloader( # function name can be pdf_downloader
19
20
  context: 'AgentContext',
20
21
  url: str,
@@ -6,12 +6,13 @@ from typing import Dict, Any, List as TypingList, Type, TYPE_CHECKING, Optional,
6
6
  from autobyteus.llm.providers import LLMProvider
7
7
  from autobyteus.tools.tool_config import ToolConfig
8
8
  from autobyteus.tools.parameter_schema import ParameterSchema
9
- from autobyteus.tools.tool_category import ToolCategory
10
- from autobyteus.tools.usage.providers import (
11
- XmlSchemaProvider,
12
- JsonSchemaProvider,
13
- XmlExampleProvider,
14
- JsonExampleProvider
9
+ from autobyteus.tools.tool_origin import ToolOrigin
10
+ # Import default formatters directly to provide convenience methods
11
+ from autobyteus.tools.usage.formatters import (
12
+ DefaultXmlSchemaFormatter,
13
+ DefaultJsonSchemaFormatter,
14
+ DefaultXmlExampleFormatter,
15
+ DefaultJsonExampleFormatter
15
16
  )
16
17
 
17
18
  if TYPE_CHECKING:
@@ -22,13 +23,14 @@ logger = logging.getLogger(__name__)
22
23
  class ToolDefinition:
23
24
  """
24
25
  Represents the definition of a tool, containing its metadata and the means
25
- to create an instance. It can generate provider-specific usage information on demand.
26
+ to create an instance. It can generate provider-agnostic usage information on demand.
26
27
  """
27
28
  def __init__(self,
28
29
  name: str,
29
30
  description: str,
30
31
  argument_schema: Optional['ParameterSchema'],
31
- category: ToolCategory,
32
+ origin: ToolOrigin,
33
+ category: str,
32
34
  config_schema: Optional['ParameterSchema'] = None,
33
35
  tool_class: Optional[Type['BaseTool']] = None,
34
36
  custom_factory: Optional[Callable[['ToolConfig'], 'BaseTool']] = None,
@@ -55,12 +57,12 @@ class ToolDefinition:
55
57
  raise TypeError(f"ToolDefinition '{name}' received an invalid 'argument_schema'. Expected ParameterSchema or None.")
56
58
  if config_schema is not None and not isinstance(config_schema, ParameterSchema):
57
59
  raise TypeError(f"ToolDefinition '{name}' received an invalid 'config_schema'. Expected ParameterSchema or None.")
58
- if not isinstance(category, ToolCategory):
59
- raise TypeError(f"ToolDefinition '{name}' requires a ToolCategory for 'category'. Got {type(category)}")
60
+ if not isinstance(origin, ToolOrigin):
61
+ raise TypeError(f"ToolDefinition '{name}' requires a ToolOrigin for 'origin'. Got {type(origin)}")
60
62
 
61
63
  # Validation for MCP-specific metadata
62
- if category == ToolCategory.MCP and not (metadata and metadata.get("mcp_server_id")):
63
- raise ValueError(f"ToolDefinition '{name}' with category MCP must provide a 'mcp_server_id' in its metadata.")
64
+ if origin == ToolOrigin.MCP and not (metadata and metadata.get("mcp_server_id")):
65
+ raise ValueError(f"ToolDefinition '{name}' with origin MCP must provide a 'mcp_server_id' in its metadata.")
64
66
 
65
67
  self._name = name
66
68
  self._description = description
@@ -68,6 +70,7 @@ class ToolDefinition:
68
70
  self._config_schema: Optional['ParameterSchema'] = config_schema
69
71
  self._tool_class = tool_class
70
72
  self._custom_factory = custom_factory
73
+ self._origin = origin
71
74
  self._category = category
72
75
  self._metadata = metadata or {}
73
76
 
@@ -87,48 +90,44 @@ class ToolDefinition:
87
90
  @property
88
91
  def config_schema(self) -> Optional['ParameterSchema']: return self._config_schema
89
92
  @property
90
- def category(self) -> ToolCategory: return self._category
93
+ def origin(self) -> ToolOrigin: return self._origin
94
+ @property
95
+ def category(self) -> str: return self._category
91
96
  @property
92
97
  def metadata(self) -> Dict[str, Any]: return self._metadata
93
98
 
94
- # --- Schema Generation API ---
99
+ # --- Convenience Schema/Example Generation API (using default formatters) ---
95
100
  def get_usage_xml(self, provider: Optional[LLMProvider] = None) -> str:
96
101
  """
97
- Generates the standardized XML usage schema string for this tool.
98
- The provider argument is included for API consistency and future-proofing.
102
+ Generates the default XML usage schema string for this tool.
103
+ The provider argument is ignored, kept for API consistency.
99
104
  """
100
- provider_instance = XmlSchemaProvider()
101
- return provider_instance.provide(self, llm_provider=provider)
105
+ formatter = DefaultXmlSchemaFormatter()
106
+ return formatter.provide(self)
102
107
 
103
108
  def get_usage_json(self, provider: Optional[LLMProvider] = None) -> Dict[str, Any]:
104
109
  """
105
- Generates the usage schema as a dictionary.
106
-
107
- Args:
108
- provider: If provided, generates a provider-specific JSON format.
109
- If None, generates a default, generic JSON format.
110
-
111
- Returns:
112
- A dictionary representing the tool's usage schema.
110
+ Generates the default JSON usage schema as a dictionary.
111
+ The provider argument is ignored, kept for API consistency.
113
112
  """
114
- provider_instance = JsonSchemaProvider()
115
- return provider_instance.provide(self, llm_provider=provider)
113
+ formatter = DefaultJsonSchemaFormatter()
114
+ return formatter.provide(self)
116
115
 
117
- # --- Example Generation API ---
118
116
  def get_usage_xml_example(self, provider: Optional[LLMProvider] = None) -> str:
119
117
  """
120
- Generates a standardized XML usage example string for this tool.
121
- The provider argument is included for API consistency and future-proofing.
118
+ Generates a default XML usage example string for this tool.
119
+ The provider argument is ignored, kept for API consistency.
122
120
  """
123
- provider_instance = XmlExampleProvider()
124
- return provider_instance.provide(self, llm_provider=provider)
121
+ formatter = DefaultXmlExampleFormatter()
122
+ return formatter.provide(self)
125
123
 
126
124
  def get_usage_json_example(self, provider: Optional[LLMProvider] = None) -> Any:
127
125
  """
128
- Generates a usage example, either as a dict or a string.
126
+ Generates a default JSON usage example as a dictionary.
127
+ The provider argument is ignored, kept for API consistency.
129
128
  """
130
- provider_instance = JsonExampleProvider()
131
- return provider_instance.provide(self, llm_provider=provider)
129
+ formatter = DefaultJsonExampleFormatter()
130
+ return formatter.provide(self)
132
131
 
133
132
  # --- Other methods ---
134
133
  @property
@@ -145,4 +144,4 @@ class ToolDefinition:
145
144
  def __repr__(self) -> str:
146
145
  creator_repr = f"class='{self._tool_class.__name__}'" if self._tool_class else "factory=True"
147
146
  metadata_repr = f", metadata={self.metadata}" if self.metadata else ""
148
- return (f"ToolDefinition(name='{self.name}', category='{self.category.value}'{metadata_repr}, {creator_repr})")
147
+ return (f"ToolDefinition(name='{self.name}', origin='{self.origin.value}', category='{self.category}'{metadata_repr}, {creator_repr})")
@@ -1,11 +1,12 @@
1
1
  # file: autobyteus/tools/registry/tool_registry.py
2
2
  import logging
3
3
  from typing import Dict, List, Optional, Type, TYPE_CHECKING
4
+ from collections import defaultdict
4
5
 
5
6
  from autobyteus.tools.registry.tool_definition import ToolDefinition
6
7
  from autobyteus.utils.singleton import SingletonMeta
7
8
  from autobyteus.tools.tool_config import ToolConfig
8
- from autobyteus.tools.tool_category import ToolCategory
9
+ from autobyteus.tools.tool_origin import ToolOrigin
9
10
 
10
11
  if TYPE_CHECKING:
11
12
  from autobyteus.tools.base_tool import BaseTool
@@ -141,7 +142,54 @@ class ToolRegistry(metaclass=SingletonMeta):
141
142
 
142
143
  return [
143
144
  td for td in self._definitions.values()
144
- if td.category == ToolCategory.MCP and td.metadata.get("mcp_server_id") == server_id
145
+ if td.origin == ToolOrigin.MCP and td.metadata.get("mcp_server_id") == server_id
145
146
  ]
146
147
 
148
+ def get_tools_by_category(self, category: str) -> List[ToolDefinition]:
149
+ """
150
+ Returns a list of all registered tool definitions that match a specific category.
151
+
152
+ Args:
153
+ category: The category string to filter by.
154
+
155
+ Returns:
156
+ A list of matching ToolDefinition objects, sorted by name.
157
+ """
158
+ if not category:
159
+ return []
160
+
161
+ matching_tools = [
162
+ td for td in self._definitions.values() if td.category == category
163
+ ]
164
+ return sorted(matching_tools, key=lambda td: td.name)
165
+
166
+ def get_tools_grouped_by_category(self, origin: Optional[ToolOrigin] = None) -> Dict[str, List[ToolDefinition]]:
167
+ """
168
+ Returns all registered tool definitions, grouped into a dictionary by their category.
169
+ Can optionally filter by tool origin before grouping.
170
+
171
+ Args:
172
+ origin: If provided, only tools from this origin will be included.
173
+
174
+ Returns:
175
+ A dictionary where keys are category strings and values are lists
176
+ of ToolDefinition objects belonging to that category. Both the categories
177
+ and the tools within each category are sorted alphabetically.
178
+ """
179
+ grouped_tools = defaultdict(list)
180
+
181
+ tools_to_process = self._definitions.values()
182
+ if origin:
183
+ tools_to_process = [td for td in tools_to_process if td.origin == origin]
184
+
185
+ for td in tools_to_process:
186
+ grouped_tools[td.category].append(td)
187
+
188
+ # Sort tools within each category and sort the categories themselves for deterministic output
189
+ sorted_grouped_tools = {}
190
+ for category in sorted(grouped_tools.keys()):
191
+ sorted_grouped_tools[category] = sorted(grouped_tools[category], key=lambda td: td.name)
192
+
193
+ return sorted_grouped_tools
194
+
147
195
  default_tool_registry = ToolRegistry()
autobyteus/tools/timer.py CHANGED
@@ -3,6 +3,7 @@ from typing import Optional, TYPE_CHECKING, Any
3
3
  from autobyteus.tools.base_tool import BaseTool
4
4
  from autobyteus.tools.tool_config import ToolConfig
5
5
  from autobyteus.tools.parameter_schema import ParameterSchema, ParameterDefinition, ParameterType
6
+ from autobyteus.tools.tool_category import ToolCategory
6
7
  from autobyteus.events.event_emitter import EventEmitter
7
8
  from autobyteus.events.event_types import EventType
8
9
  import logging
@@ -17,6 +18,7 @@ class Timer(BaseTool, EventEmitter):
17
18
  A tool that provides timer functionality with configurable duration and event emission.
18
19
  The timer runs independently after being started and emits TIMER_UPDATE events.
19
20
  """
21
+ CATEGORY = ToolCategory.UTILITY
20
22
 
21
23
  def __init__(self, config: Optional[ToolConfig] = None):
22
24
  BaseTool.__init__(self, config=config)
@@ -2,10 +2,21 @@
2
2
  from enum import Enum
3
3
 
4
4
  class ToolCategory(str, Enum):
5
- """Enumeration of tool categories to identify their origin."""
6
- LOCAL = "local"
7
- MCP = "mcp"
8
- # BUILT_IN, USER_DEFINED etc. could be added later.
5
+ """
6
+ Provides standardized string constants for common tool categories.
7
+ While tools can use any string for a category, using these constants
8
+ is recommended to ensure consistency in UI grouping.
9
+ """
10
+ USER_INTERACTION = "User Interaction"
11
+ FILE_SYSTEM = "File System"
12
+ WEB = "Web"
13
+ SYSTEM = "System"
14
+ UTILITY = "Utility"
15
+ AGENT_COMMUNICATION = "Agent Communication"
16
+ PROMPT_MANAGEMENT = "Prompt Management"
17
+ TASK_MANAGEMENT = "Task Management" # NEW CATEGORY ADDED
18
+ GENERAL = "General"
19
+ MCP = "MCP"
9
20
 
10
21
  def __str__(self) -> str:
11
22
  return self.value
@@ -5,6 +5,7 @@ from typing import Dict, Any
5
5
 
6
6
  from autobyteus.tools.registry import default_tool_registry, ToolDefinition
7
7
  from autobyteus.tools.parameter_schema import ParameterSchema
8
+ from autobyteus.tools.tool_origin import ToolOrigin
8
9
  from autobyteus.tools.tool_category import ToolCategory
9
10
 
10
11
  logger = logging.getLogger(__name__)
@@ -53,6 +54,9 @@ class ToolMeta(ABCMeta):
53
54
  instantiation_config_schema = None
54
55
  except Exception as e:
55
56
  logger.warning(f"Tool class {name} ({tool_name}) has get_config_schema() but it failed: {e}. Assuming no instantiation config.")
57
+
58
+ # Get category from class attribute, defaulting to "General"
59
+ category_str = getattr(cls, 'CATEGORY', ToolCategory.GENERAL)
56
60
 
57
61
  # Create the definition without pre-generating usage strings
58
62
  definition = ToolDefinition(
@@ -62,7 +66,8 @@ class ToolMeta(ABCMeta):
62
66
  custom_factory=None,
63
67
  argument_schema=argument_schema,
64
68
  config_schema=instantiation_config_schema,
65
- category=ToolCategory.LOCAL
69
+ origin=ToolOrigin.LOCAL,
70
+ category=category_str
66
71
  )
67
72
  default_tool_registry.register_tool(definition)
68
73
 
@@ -0,0 +1,10 @@
1
+ # file: autobyteus/autobyteus/tools/tool_origin.py
2
+ from enum import Enum
3
+
4
+ class ToolOrigin(str, Enum):
5
+ """Enumeration of tool origins to identify their execution model."""
6
+ LOCAL = "local"
7
+ MCP = "mcp"
8
+
9
+ def __str__(self) -> str:
10
+ return self.value
@@ -1,5 +1,5 @@
1
1
  # file: autobyteus/autobyteus/tools/usage/formatters/default_json_example_formatter.py
2
- from typing import Dict, Any, TYPE_CHECKING
2
+ from typing import Dict, Any, TYPE_CHECKING, List, Optional
3
3
 
4
4
  from autobyteus.tools.parameter_schema import ParameterType, ParameterDefinition
5
5
  from .base_formatter import BaseExampleFormatter
@@ -9,8 +9,8 @@ if TYPE_CHECKING:
9
9
 
10
10
  class DefaultJsonExampleFormatter(BaseExampleFormatter):
11
11
  """
12
- Formats a tool usage example into a generic JSON format, inspired by
13
- the default XML format.
12
+ Formats a tool usage example into a generic JSON format.
13
+ It intelligently generates detailed examples for complex object schemas.
14
14
  """
15
15
 
16
16
  def provide(self, tool_definition: 'ToolDefinition') -> Dict:
@@ -20,6 +20,8 @@ class DefaultJsonExampleFormatter(BaseExampleFormatter):
20
20
 
21
21
  if arg_schema and arg_schema.parameters:
22
22
  for param_def in arg_schema.parameters:
23
+ # Always include required parameters in the example.
24
+ # Also include optional parameters that have a default value to show common usage.
23
25
  if param_def.required or param_def.default_value is not None:
24
26
  arguments[param_def.name] = self._generate_placeholder_value(param_def)
25
27
 
@@ -31,6 +33,12 @@ class DefaultJsonExampleFormatter(BaseExampleFormatter):
31
33
  }
32
34
 
33
35
  def _generate_placeholder_value(self, param_def: ParameterDefinition) -> Any:
36
+ # If an object parameter has a detailed schema, generate a structured example from it.
37
+ if param_def.param_type == ParameterType.OBJECT and param_def.object_schema:
38
+ # We pass the full schema document to allow for resolving $refs
39
+ return DefaultJsonExampleFormatter._generate_example_from_schema(param_def.object_schema, param_def.object_schema)
40
+
41
+ # Fallback to simple placeholder generation for primitives or objects without schemas.
34
42
  if param_def.default_value is not None: return param_def.default_value
35
43
  if param_def.param_type == ParameterType.STRING: return f"example_{param_def.name}"
36
44
  if param_def.param_type == ParameterType.INTEGER: return 123
@@ -40,3 +48,70 @@ class DefaultJsonExampleFormatter(BaseExampleFormatter):
40
48
  if param_def.param_type == ParameterType.OBJECT: return {"key": "value"}
41
49
  if param_def.param_type == ParameterType.ARRAY: return ["item1", "item2"]
42
50
  return "placeholder"
51
+
52
+ @staticmethod
53
+ def _generate_example_from_schema(sub_schema: Dict[str, Any], full_schema: Dict[str, Any]) -> Any:
54
+ """
55
+ Recursively generates an example value from a JSON schema dictionary.
56
+ This is a static method so it can be reused by other formatters.
57
+ """
58
+ if "$ref" in sub_schema:
59
+ ref_path = sub_schema["$ref"]
60
+ try:
61
+ # Resolve the reference, e.g., "#/$defs/MySchema"
62
+ parts = ref_path.lstrip("#/").split("/")
63
+ resolved_schema = full_schema
64
+ for part in parts:
65
+ resolved_schema = resolved_schema[part]
66
+ return DefaultJsonExampleFormatter._generate_example_from_schema(resolved_schema, full_schema)
67
+ except (KeyError, IndexError):
68
+ return {"error": f"Could not resolve schema reference: {ref_path}"}
69
+
70
+ schema_type = sub_schema.get("type")
71
+
72
+ if "default" in sub_schema:
73
+ return sub_schema["default"]
74
+
75
+ if "enum" in sub_schema and sub_schema["enum"]:
76
+ return sub_schema["enum"][0]
77
+
78
+ if schema_type == "object":
79
+ example_obj = {}
80
+ properties = sub_schema.get("properties", {})
81
+ required_fields = sub_schema.get("required", [])
82
+ for prop_name, prop_schema in properties.items():
83
+ # Include required fields and a subset of optional fields for a concise example.
84
+ if prop_name in required_fields:
85
+ example_obj[prop_name] = DefaultJsonExampleFormatter._generate_example_from_schema(prop_schema, full_schema)
86
+ return example_obj
87
+
88
+ elif schema_type == "array":
89
+ items_schema = sub_schema.get("items")
90
+ if isinstance(items_schema, dict):
91
+ # Generate one example item for the array to keep it concise
92
+ return [DefaultJsonExampleFormatter._generate_example_from_schema(items_schema, full_schema)]
93
+ else:
94
+ return ["example_item_1"]
95
+
96
+ elif schema_type == "string":
97
+ description = sub_schema.get("description", "")
98
+ if "e.g." in description.lower():
99
+ try:
100
+ return description.split("e.g.,")[1].split(')')[0].strip().strip("'\"")
101
+ except IndexError:
102
+ pass
103
+ return "example_string"
104
+
105
+ elif schema_type == "integer":
106
+ return 1
107
+
108
+ elif schema_type == "number":
109
+ return 1.1
110
+
111
+ elif schema_type == "boolean":
112
+ return True
113
+
114
+ elif schema_type == "null":
115
+ return None
116
+
117
+ return "unknown_type"
@@ -1,9 +1,11 @@
1
1
  # file: autobyteus/autobyteus/tools/usage/formatters/default_xml_example_formatter.py
2
2
  import xml.sax.saxutils
3
+ import json # Import json for embedding complex objects
3
4
  from typing import Any, TYPE_CHECKING
4
5
 
5
6
  from autobyteus.tools.parameter_schema import ParameterType, ParameterDefinition
6
7
  from .base_formatter import BaseExampleFormatter
8
+ from .default_json_example_formatter import DefaultJsonExampleFormatter # Import for reuse
7
9
 
8
10
  if TYPE_CHECKING:
9
11
  from autobyteus.tools.registry import ToolDefinition
@@ -22,8 +24,21 @@ class DefaultXmlExampleFormatter(BaseExampleFormatter):
22
24
  for param_def in arg_schema.parameters:
23
25
  if param_def.required or param_def.default_value is not None:
24
26
  placeholder_value = self._generate_placeholder_value(param_def)
25
- escaped_value = xml.sax.saxutils.escape(str(placeholder_value))
26
- arguments_part.append(f' <arg name="{param_def.name}">{escaped_value}</arg>')
27
+ # For complex objects/arrays, we now get a dict/list.
28
+ # Convert it to a JSON string for embedding in XML.
29
+ if isinstance(placeholder_value, (dict, list)):
30
+ value_str = json.dumps(placeholder_value, indent=2)
31
+ else:
32
+ value_str = str(placeholder_value)
33
+
34
+ escaped_value = xml.sax.saxutils.escape(value_str)
35
+
36
+ # Add newlines for readability if the value is a multiline JSON string
37
+ if '\n' in escaped_value:
38
+ arguments_part.append(f' <arg name="{param_def.name}">\n{escaped_value}\n </arg>')
39
+ else:
40
+ arguments_part.append(f' <arg name="{param_def.name}">{escaped_value}</arg>')
41
+
27
42
 
28
43
  if arguments_part:
29
44
  example_xml_parts.append(" <arguments>")
@@ -36,6 +51,11 @@ class DefaultXmlExampleFormatter(BaseExampleFormatter):
36
51
  return "\n".join(example_xml_parts)
37
52
 
38
53
  def _generate_placeholder_value(self, param_def: ParameterDefinition) -> Any:
54
+ # REUSE a more intelligent generator for complex objects
55
+ if param_def.param_type == ParameterType.OBJECT and param_def.object_schema:
56
+ return DefaultJsonExampleFormatter._generate_example_from_schema(param_def.object_schema, param_def.object_schema)
57
+
58
+ # Fallback for primitives
39
59
  if param_def.default_value is not None:
40
60
  return param_def.default_value
41
61
  if param_def.param_type == ParameterType.STRING:
@@ -49,7 +69,7 @@ class DefaultXmlExampleFormatter(BaseExampleFormatter):
49
69
  if param_def.param_type == ParameterType.ENUM:
50
70
  return param_def.enum_values[0] if param_def.enum_values else "enum_val"
51
71
  if param_def.param_type == ParameterType.OBJECT:
52
- return {"key": "value"}
72
+ return {"key": "value"} # Fallback if no schema
53
73
  if param_def.param_type == ParameterType.ARRAY:
54
74
  return ["item1", "item2"]
55
75
  return "placeholder"
@@ -3,6 +3,7 @@ from typing import Dict, Any, TYPE_CHECKING
3
3
 
4
4
  from autobyteus.tools.parameter_schema import ParameterType, ParameterDefinition
5
5
  from .base_formatter import BaseExampleFormatter
6
+ from .default_json_example_formatter import DefaultJsonExampleFormatter # Import for reuse
6
7
 
7
8
  if TYPE_CHECKING:
8
9
  from autobyteus.tools.registry import ToolDefinition
@@ -23,6 +24,11 @@ class GeminiJsonExampleFormatter(BaseExampleFormatter):
23
24
  return {"name": tool_name, "args": arguments}
24
25
 
25
26
  def _generate_placeholder_value(self, param_def: ParameterDefinition) -> Any:
27
+ # REUSE a more intelligent generator for complex objects
28
+ if param_def.param_type == ParameterType.OBJECT and param_def.object_schema:
29
+ return DefaultJsonExampleFormatter._generate_example_from_schema(param_def.object_schema, param_def.object_schema)
30
+
31
+ # Fallback for primitives
26
32
  if param_def.default_value is not None: return param_def.default_value
27
33
  if param_def.param_type == ParameterType.STRING: return f"example_{param_def.name}"
28
34
  if param_def.param_type == ParameterType.INTEGER: return 123
@@ -3,6 +3,8 @@ from typing import Dict, Any, TYPE_CHECKING
3
3
 
4
4
  from autobyteus.tools.parameter_schema import ParameterType, ParameterDefinition
5
5
  from .base_formatter import BaseExampleFormatter
6
+ # Import for reuse of the intelligent example generation logic
7
+ from .default_json_example_formatter import DefaultJsonExampleFormatter
6
8
 
7
9
  if TYPE_CHECKING:
8
10
  from autobyteus.tools.registry import ToolDefinition
@@ -23,6 +25,11 @@ class GoogleJsonExampleFormatter(BaseExampleFormatter):
23
25
  return {"name": tool_name, "args": arguments}
24
26
 
25
27
  def _generate_placeholder_value(self, param_def: ParameterDefinition) -> Any:
28
+ # REUSE the intelligent generator for complex objects
29
+ if param_def.param_type == ParameterType.OBJECT and param_def.object_schema:
30
+ return DefaultJsonExampleFormatter._generate_example_from_schema(param_def.object_schema, param_def.object_schema)
31
+
32
+ # Fallback for primitives
26
33
  if param_def.default_value is not None: return param_def.default_value
27
34
  if param_def.param_type == ParameterType.STRING: return f"example_{param_def.name}"
28
35
  if param_def.param_type == ParameterType.INTEGER: return 123
@@ -4,6 +4,7 @@ from typing import Dict, Any, TYPE_CHECKING
4
4
 
5
5
  from autobyteus.tools.parameter_schema import ParameterType, ParameterDefinition
6
6
  from .base_formatter import BaseExampleFormatter
7
+ from .default_json_example_formatter import DefaultJsonExampleFormatter # Import for reuse
7
8
 
8
9
  if TYPE_CHECKING:
9
10
  from autobyteus.tools.registry import ToolDefinition
@@ -12,7 +13,6 @@ class OpenAiJsonExampleFormatter(BaseExampleFormatter):
12
13
  """
13
14
  Formats a tool usage example into a format resembling an entry in the
14
15
  OpenAI JSON 'tool_calls' array, intended for prompting a model.
15
- The output is wrapped in a 'tool' key for consistency in prompts.
16
16
  """
17
17
 
18
18
  def provide(self, tool_definition: 'ToolDefinition') -> Dict:
@@ -25,8 +25,6 @@ class OpenAiJsonExampleFormatter(BaseExampleFormatter):
25
25
  if param_def.required or param_def.default_value is not None:
26
26
  arguments[param_def.name] = self._generate_placeholder_value(param_def)
27
27
 
28
- # This format contains the 'function' wrapper with a stringified 'arguments' field.
29
- # This aligns with the structure often seen inside an OpenAI API tool_calls object.
30
28
  function_call = {
31
29
  "function": {
32
30
  "name": tool_name,
@@ -34,10 +32,14 @@ class OpenAiJsonExampleFormatter(BaseExampleFormatter):
34
32
  },
35
33
  }
36
34
 
37
- # Wrap in a 'tool' key for consistency in prompt generation.
38
35
  return {"tool": function_call}
39
36
 
40
37
  def _generate_placeholder_value(self, param_def: ParameterDefinition) -> Any:
38
+ # REUSE a more intelligent generator for complex objects
39
+ if param_def.param_type == ParameterType.OBJECT and param_def.object_schema:
40
+ return DefaultJsonExampleFormatter._generate_example_from_schema(param_def.object_schema, param_def.object_schema)
41
+
42
+ # Fallback for primitives
41
43
  if param_def.default_value is not None: return param_def.default_value
42
44
  if param_def.param_type == ParameterType.STRING: return f"example_{param_def.name}"
43
45
  if param_def.param_type == ParameterType.INTEGER: return 123