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.
- autobyteus/agent/agent.py +1 -1
- autobyteus/agent/bootstrap_steps/system_prompt_processing_step.py +4 -2
- autobyteus/agent/context/__init__.py +4 -2
- autobyteus/agent/context/agent_config.py +35 -8
- autobyteus/agent/context/agent_context_registry.py +73 -0
- autobyteus/agent/events/notifiers.py +4 -0
- autobyteus/agent/events/worker_event_dispatcher.py +1 -2
- autobyteus/agent/handlers/inter_agent_message_event_handler.py +8 -3
- autobyteus/agent/handlers/llm_complete_response_received_event_handler.py +19 -19
- autobyteus/agent/handlers/llm_user_message_ready_event_handler.py +2 -2
- autobyteus/agent/handlers/tool_result_event_handler.py +48 -20
- autobyteus/agent/handlers/user_input_message_event_handler.py +16 -1
- autobyteus/agent/input_processor/__init__.py +1 -7
- autobyteus/agent/message/context_file_type.py +6 -0
- autobyteus/agent/message/send_message_to.py +74 -99
- autobyteus/agent/phases/discover.py +2 -1
- autobyteus/agent/runtime/agent_runtime.py +10 -2
- autobyteus/agent/runtime/agent_worker.py +1 -0
- autobyteus/agent/sender_type.py +15 -0
- autobyteus/agent/streaming/agent_event_stream.py +6 -0
- autobyteus/agent/streaming/stream_event_payloads.py +12 -0
- autobyteus/agent/streaming/stream_events.py +3 -0
- autobyteus/agent/system_prompt_processor/tool_manifest_injector_processor.py +7 -4
- autobyteus/agent/tool_execution_result_processor/__init__.py +9 -0
- autobyteus/agent/tool_execution_result_processor/base_processor.py +46 -0
- autobyteus/agent/tool_execution_result_processor/processor_definition.py +36 -0
- autobyteus/agent/tool_execution_result_processor/processor_meta.py +36 -0
- autobyteus/agent/tool_execution_result_processor/processor_registry.py +70 -0
- autobyteus/agent/workspace/base_workspace.py +17 -2
- autobyteus/agent_team/__init__.py +1 -0
- autobyteus/agent_team/agent_team.py +93 -0
- autobyteus/agent_team/agent_team_builder.py +184 -0
- autobyteus/agent_team/base_agent_team.py +86 -0
- autobyteus/agent_team/bootstrap_steps/__init__.py +24 -0
- autobyteus/agent_team/bootstrap_steps/agent_configuration_preparation_step.py +73 -0
- autobyteus/agent_team/bootstrap_steps/agent_team_bootstrapper.py +54 -0
- autobyteus/agent_team/bootstrap_steps/agent_team_runtime_queue_initialization_step.py +25 -0
- autobyteus/agent_team/bootstrap_steps/base_agent_team_bootstrap_step.py +23 -0
- autobyteus/agent_team/bootstrap_steps/coordinator_initialization_step.py +41 -0
- autobyteus/agent_team/bootstrap_steps/coordinator_prompt_preparation_step.py +85 -0
- autobyteus/agent_team/bootstrap_steps/task_notifier_initialization_step.py +51 -0
- autobyteus/agent_team/bootstrap_steps/team_context_initialization_step.py +45 -0
- autobyteus/agent_team/context/__init__.py +17 -0
- autobyteus/agent_team/context/agent_team_config.py +33 -0
- autobyteus/agent_team/context/agent_team_context.py +61 -0
- autobyteus/agent_team/context/agent_team_runtime_state.py +56 -0
- autobyteus/agent_team/context/team_manager.py +147 -0
- autobyteus/agent_team/context/team_node_config.py +76 -0
- autobyteus/agent_team/events/__init__.py +29 -0
- autobyteus/agent_team/events/agent_team_event_dispatcher.py +39 -0
- autobyteus/agent_team/events/agent_team_events.py +53 -0
- autobyteus/agent_team/events/agent_team_input_event_queue_manager.py +21 -0
- autobyteus/agent_team/exceptions.py +8 -0
- autobyteus/agent_team/factory/__init__.py +9 -0
- autobyteus/agent_team/factory/agent_team_factory.py +99 -0
- autobyteus/agent_team/handlers/__init__.py +19 -0
- autobyteus/agent_team/handlers/agent_team_event_handler_registry.py +23 -0
- autobyteus/agent_team/handlers/base_agent_team_event_handler.py +16 -0
- autobyteus/agent_team/handlers/inter_agent_message_request_event_handler.py +61 -0
- autobyteus/agent_team/handlers/lifecycle_agent_team_event_handler.py +27 -0
- autobyteus/agent_team/handlers/process_user_message_event_handler.py +46 -0
- autobyteus/agent_team/handlers/tool_approval_team_event_handler.py +48 -0
- autobyteus/agent_team/phases/__init__.py +11 -0
- autobyteus/agent_team/phases/agent_team_operational_phase.py +19 -0
- autobyteus/agent_team/phases/agent_team_phase_manager.py +48 -0
- autobyteus/agent_team/runtime/__init__.py +13 -0
- autobyteus/agent_team/runtime/agent_team_runtime.py +82 -0
- autobyteus/agent_team/runtime/agent_team_worker.py +117 -0
- autobyteus/agent_team/shutdown_steps/__init__.py +17 -0
- autobyteus/agent_team/shutdown_steps/agent_team_shutdown_orchestrator.py +35 -0
- autobyteus/agent_team/shutdown_steps/agent_team_shutdown_step.py +42 -0
- autobyteus/agent_team/shutdown_steps/base_agent_team_shutdown_step.py +16 -0
- autobyteus/agent_team/shutdown_steps/bridge_cleanup_step.py +28 -0
- autobyteus/agent_team/shutdown_steps/sub_team_shutdown_step.py +41 -0
- autobyteus/agent_team/streaming/__init__.py +26 -0
- autobyteus/agent_team/streaming/agent_event_bridge.py +48 -0
- autobyteus/agent_team/streaming/agent_event_multiplexer.py +70 -0
- autobyteus/agent_team/streaming/agent_team_event_notifier.py +64 -0
- autobyteus/agent_team/streaming/agent_team_event_stream.py +33 -0
- autobyteus/agent_team/streaming/agent_team_stream_event_payloads.py +32 -0
- autobyteus/agent_team/streaming/agent_team_stream_events.py +56 -0
- autobyteus/agent_team/streaming/team_event_bridge.py +50 -0
- autobyteus/agent_team/task_notification/__init__.py +11 -0
- autobyteus/agent_team/task_notification/system_event_driven_agent_task_notifier.py +164 -0
- autobyteus/agent_team/task_notification/task_notification_mode.py +24 -0
- autobyteus/agent_team/utils/__init__.py +9 -0
- autobyteus/agent_team/utils/wait_for_idle.py +46 -0
- autobyteus/cli/__init__.py +1 -1
- autobyteus/cli/agent_team_tui/__init__.py +4 -0
- autobyteus/cli/agent_team_tui/app.py +210 -0
- autobyteus/cli/agent_team_tui/state.py +180 -0
- autobyteus/cli/agent_team_tui/widgets/__init__.py +6 -0
- autobyteus/cli/agent_team_tui/widgets/agent_list_sidebar.py +149 -0
- autobyteus/cli/agent_team_tui/widgets/focus_pane.py +320 -0
- autobyteus/cli/agent_team_tui/widgets/logo.py +20 -0
- autobyteus/cli/agent_team_tui/widgets/renderables.py +77 -0
- autobyteus/cli/agent_team_tui/widgets/shared.py +60 -0
- autobyteus/cli/agent_team_tui/widgets/status_bar.py +14 -0
- autobyteus/cli/agent_team_tui/widgets/task_board_panel.py +82 -0
- autobyteus/cli/cli_display.py +1 -1
- autobyteus/cli/workflow_tui/__init__.py +4 -0
- autobyteus/cli/workflow_tui/app.py +210 -0
- autobyteus/cli/workflow_tui/state.py +189 -0
- autobyteus/cli/workflow_tui/widgets/__init__.py +6 -0
- autobyteus/cli/workflow_tui/widgets/agent_list_sidebar.py +149 -0
- autobyteus/cli/workflow_tui/widgets/focus_pane.py +335 -0
- autobyteus/cli/workflow_tui/widgets/logo.py +27 -0
- autobyteus/cli/workflow_tui/widgets/renderables.py +70 -0
- autobyteus/cli/workflow_tui/widgets/shared.py +51 -0
- autobyteus/cli/workflow_tui/widgets/status_bar.py +14 -0
- autobyteus/events/event_types.py +8 -0
- autobyteus/llm/api/autobyteus_llm.py +11 -12
- autobyteus/llm/api/lmstudio_llm.py +34 -0
- autobyteus/llm/api/ollama_llm.py +8 -13
- autobyteus/llm/api/openai_compatible_llm.py +20 -3
- autobyteus/llm/autobyteus_provider.py +73 -46
- autobyteus/llm/llm_factory.py +103 -139
- autobyteus/llm/lmstudio_provider.py +104 -0
- autobyteus/llm/models.py +83 -53
- autobyteus/llm/ollama_provider.py +69 -61
- autobyteus/llm/ollama_provider_resolver.py +1 -0
- autobyteus/llm/providers.py +13 -12
- autobyteus/llm/runtimes.py +11 -0
- autobyteus/llm/token_counter/token_counter_factory.py +2 -0
- autobyteus/task_management/__init__.py +43 -0
- autobyteus/task_management/base_task_board.py +68 -0
- autobyteus/task_management/converters/__init__.py +11 -0
- autobyteus/task_management/converters/task_board_converter.py +64 -0
- autobyteus/task_management/converters/task_plan_converter.py +48 -0
- autobyteus/task_management/deliverable.py +16 -0
- autobyteus/task_management/deliverables/__init__.py +8 -0
- autobyteus/task_management/deliverables/file_deliverable.py +15 -0
- autobyteus/task_management/events.py +27 -0
- autobyteus/task_management/in_memory_task_board.py +126 -0
- autobyteus/task_management/schemas/__init__.py +15 -0
- autobyteus/task_management/schemas/deliverable_schema.py +13 -0
- autobyteus/task_management/schemas/plan_definition.py +35 -0
- autobyteus/task_management/schemas/task_status_report.py +27 -0
- autobyteus/task_management/task_plan.py +110 -0
- autobyteus/task_management/tools/__init__.py +14 -0
- autobyteus/task_management/tools/get_task_board_status.py +68 -0
- autobyteus/task_management/tools/publish_task_plan.py +113 -0
- autobyteus/task_management/tools/update_task_status.py +135 -0
- autobyteus/tools/__init__.py +2 -0
- autobyteus/tools/ask_user_input.py +2 -1
- autobyteus/tools/bash/bash_executor.py +61 -15
- autobyteus/tools/browser/session_aware/browser_session_aware_navigate_to.py +2 -0
- autobyteus/tools/browser/session_aware/browser_session_aware_web_element_trigger.py +3 -0
- autobyteus/tools/browser/session_aware/browser_session_aware_webpage_reader.py +3 -0
- autobyteus/tools/browser/session_aware/browser_session_aware_webpage_screenshot_taker.py +3 -0
- autobyteus/tools/browser/standalone/google_search_ui.py +2 -0
- autobyteus/tools/browser/standalone/navigate_to.py +2 -0
- autobyteus/tools/browser/standalone/web_page_pdf_generator.py +3 -0
- autobyteus/tools/browser/standalone/webpage_image_downloader.py +3 -0
- autobyteus/tools/browser/standalone/webpage_reader.py +2 -0
- autobyteus/tools/browser/standalone/webpage_screenshot_taker.py +3 -0
- autobyteus/tools/file/file_reader.py +36 -9
- autobyteus/tools/file/file_writer.py +37 -9
- autobyteus/tools/functional_tool.py +5 -4
- autobyteus/tools/image_downloader.py +2 -0
- autobyteus/tools/mcp/config_service.py +63 -58
- autobyteus/tools/mcp/server/http_managed_mcp_server.py +14 -2
- autobyteus/tools/mcp/server/stdio_managed_mcp_server.py +14 -2
- autobyteus/tools/mcp/server_instance_manager.py +30 -4
- autobyteus/tools/mcp/tool_registrar.py +106 -51
- autobyteus/tools/parameter_schema.py +17 -11
- autobyteus/tools/pdf_downloader.py +2 -1
- autobyteus/tools/registry/tool_definition.py +36 -37
- autobyteus/tools/registry/tool_registry.py +50 -2
- autobyteus/tools/timer.py +2 -0
- autobyteus/tools/tool_category.py +15 -4
- autobyteus/tools/tool_meta.py +6 -1
- autobyteus/tools/tool_origin.py +10 -0
- autobyteus/tools/usage/formatters/default_json_example_formatter.py +78 -3
- autobyteus/tools/usage/formatters/default_xml_example_formatter.py +23 -3
- autobyteus/tools/usage/formatters/gemini_json_example_formatter.py +6 -0
- autobyteus/tools/usage/formatters/google_json_example_formatter.py +7 -0
- autobyteus/tools/usage/formatters/openai_json_example_formatter.py +6 -4
- autobyteus/tools/usage/parsers/gemini_json_tool_usage_parser.py +23 -7
- autobyteus/tools/usage/parsers/provider_aware_tool_usage_parser.py +14 -25
- autobyteus/tools/usage/providers/__init__.py +2 -12
- autobyteus/tools/usage/providers/tool_manifest_provider.py +36 -29
- autobyteus/tools/usage/registries/__init__.py +7 -12
- autobyteus/tools/usage/registries/tool_formatter_pair.py +15 -0
- autobyteus/tools/usage/registries/tool_formatting_registry.py +58 -0
- autobyteus/tools/usage/registries/tool_usage_parser_registry.py +55 -0
- autobyteus/workflow/agentic_workflow.py +93 -0
- autobyteus/{agent/workflow → workflow}/base_agentic_workflow.py +19 -27
- autobyteus/workflow/bootstrap_steps/__init__.py +20 -0
- autobyteus/workflow/bootstrap_steps/agent_tool_injection_step.py +34 -0
- autobyteus/workflow/bootstrap_steps/base_workflow_bootstrap_step.py +23 -0
- autobyteus/workflow/bootstrap_steps/coordinator_initialization_step.py +41 -0
- autobyteus/workflow/bootstrap_steps/coordinator_prompt_preparation_step.py +108 -0
- autobyteus/workflow/bootstrap_steps/workflow_bootstrapper.py +50 -0
- autobyteus/workflow/bootstrap_steps/workflow_runtime_queue_initialization_step.py +25 -0
- autobyteus/workflow/context/__init__.py +17 -0
- autobyteus/workflow/context/team_manager.py +147 -0
- autobyteus/workflow/context/workflow_config.py +30 -0
- autobyteus/workflow/context/workflow_context.py +61 -0
- autobyteus/workflow/context/workflow_node_config.py +76 -0
- autobyteus/workflow/context/workflow_runtime_state.py +53 -0
- autobyteus/workflow/events/__init__.py +29 -0
- autobyteus/workflow/events/workflow_event_dispatcher.py +39 -0
- autobyteus/workflow/events/workflow_events.py +53 -0
- autobyteus/workflow/events/workflow_input_event_queue_manager.py +21 -0
- autobyteus/workflow/exceptions.py +8 -0
- autobyteus/workflow/factory/__init__.py +9 -0
- autobyteus/workflow/factory/workflow_factory.py +99 -0
- autobyteus/workflow/handlers/__init__.py +19 -0
- autobyteus/workflow/handlers/base_workflow_event_handler.py +16 -0
- autobyteus/workflow/handlers/inter_agent_message_request_event_handler.py +61 -0
- autobyteus/workflow/handlers/lifecycle_workflow_event_handler.py +27 -0
- autobyteus/workflow/handlers/process_user_message_event_handler.py +46 -0
- autobyteus/workflow/handlers/tool_approval_workflow_event_handler.py +39 -0
- autobyteus/workflow/handlers/workflow_event_handler_registry.py +23 -0
- autobyteus/workflow/phases/__init__.py +11 -0
- autobyteus/workflow/phases/workflow_operational_phase.py +19 -0
- autobyteus/workflow/phases/workflow_phase_manager.py +48 -0
- autobyteus/workflow/runtime/__init__.py +13 -0
- autobyteus/workflow/runtime/workflow_runtime.py +82 -0
- autobyteus/workflow/runtime/workflow_worker.py +117 -0
- autobyteus/workflow/shutdown_steps/__init__.py +17 -0
- autobyteus/workflow/shutdown_steps/agent_team_shutdown_step.py +42 -0
- autobyteus/workflow/shutdown_steps/base_workflow_shutdown_step.py +16 -0
- autobyteus/workflow/shutdown_steps/bridge_cleanup_step.py +28 -0
- autobyteus/workflow/shutdown_steps/sub_workflow_shutdown_step.py +41 -0
- autobyteus/workflow/shutdown_steps/workflow_shutdown_orchestrator.py +35 -0
- autobyteus/workflow/streaming/__init__.py +26 -0
- autobyteus/workflow/streaming/agent_event_bridge.py +48 -0
- autobyteus/workflow/streaming/agent_event_multiplexer.py +70 -0
- autobyteus/workflow/streaming/workflow_event_bridge.py +50 -0
- autobyteus/workflow/streaming/workflow_event_notifier.py +83 -0
- autobyteus/workflow/streaming/workflow_event_stream.py +33 -0
- autobyteus/workflow/streaming/workflow_stream_event_payloads.py +28 -0
- autobyteus/workflow/streaming/workflow_stream_events.py +45 -0
- autobyteus/workflow/utils/__init__.py +9 -0
- autobyteus/workflow/utils/wait_for_idle.py +46 -0
- autobyteus/workflow/workflow_builder.py +151 -0
- {autobyteus-1.1.3.dist-info → autobyteus-1.1.5.dist-info}/METADATA +16 -14
- autobyteus-1.1.5.dist-info/RECORD +455 -0
- {autobyteus-1.1.3.dist-info → autobyteus-1.1.5.dist-info}/top_level.txt +1 -0
- examples/__init__.py +1 -0
- examples/agent_team/__init__.py +1 -0
- examples/discover_phase_transitions.py +104 -0
- examples/run_browser_agent.py +262 -0
- examples/run_google_slides_agent.py +287 -0
- examples/run_mcp_browser_client.py +174 -0
- examples/run_mcp_google_slides_client.py +270 -0
- examples/run_mcp_list_tools.py +189 -0
- examples/run_poem_writer.py +284 -0
- examples/run_sqlite_agent.py +295 -0
- autobyteus/agent/context/agent_phase_manager.py +0 -264
- autobyteus/agent/context/phases.py +0 -49
- autobyteus/agent/group/__init__.py +0 -0
- autobyteus/agent/group/agent_group.py +0 -164
- autobyteus/agent/group/agent_group_context.py +0 -81
- autobyteus/agent/input_processor/content_prefixing_input_processor.py +0 -41
- autobyteus/agent/input_processor/metadata_appending_input_processor.py +0 -34
- autobyteus/agent/input_processor/passthrough_input_processor.py +0 -33
- autobyteus/agent/workflow/__init__.py +0 -11
- autobyteus/agent/workflow/agentic_workflow.py +0 -89
- autobyteus/tools/mcp/call_handlers/__init__.py +0 -16
- autobyteus/tools/mcp/call_handlers/base_handler.py +0 -40
- autobyteus/tools/mcp/call_handlers/stdio_handler.py +0 -76
- autobyteus/tools/mcp/call_handlers/streamable_http_handler.py +0 -55
- autobyteus/tools/mcp/registrar.py +0 -202
- autobyteus/tools/usage/providers/json_example_provider.py +0 -32
- autobyteus/tools/usage/providers/json_schema_provider.py +0 -35
- autobyteus/tools/usage/providers/json_tool_usage_parser_provider.py +0 -28
- autobyteus/tools/usage/providers/xml_example_provider.py +0 -28
- autobyteus/tools/usage/providers/xml_schema_provider.py +0 -29
- autobyteus/tools/usage/providers/xml_tool_usage_parser_provider.py +0 -26
- autobyteus/tools/usage/registries/json_example_formatter_registry.py +0 -51
- autobyteus/tools/usage/registries/json_schema_formatter_registry.py +0 -51
- autobyteus/tools/usage/registries/json_tool_usage_parser_registry.py +0 -42
- autobyteus/tools/usage/registries/xml_example_formatter_registry.py +0 -30
- autobyteus/tools/usage/registries/xml_schema_formatter_registry.py +0 -33
- autobyteus/tools/usage/registries/xml_tool_usage_parser_registry.py +0 -30
- autobyteus/workflow/simple_task.py +0 -98
- autobyteus/workflow/task.py +0 -147
- autobyteus/workflow/workflow.py +0 -49
- autobyteus-1.1.3.dist-info/RECORD +0 -312
- {autobyteus-1.1.3.dist-info → autobyteus-1.1.5.dist-info}/WHEEL +0 -0
- {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.
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
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-
|
|
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
|
-
|
|
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(
|
|
59
|
-
raise TypeError(f"ToolDefinition '{name}' requires a
|
|
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
|
|
63
|
-
raise ValueError(f"ToolDefinition '{name}' with
|
|
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
|
|
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
|
|
98
|
-
The provider argument is
|
|
102
|
+
Generates the default XML usage schema string for this tool.
|
|
103
|
+
The provider argument is ignored, kept for API consistency.
|
|
99
104
|
"""
|
|
100
|
-
|
|
101
|
-
return
|
|
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
|
-
|
|
115
|
-
return
|
|
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
|
|
121
|
-
The provider argument is
|
|
118
|
+
Generates a default XML usage example string for this tool.
|
|
119
|
+
The provider argument is ignored, kept for API consistency.
|
|
122
120
|
"""
|
|
123
|
-
|
|
124
|
-
return
|
|
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
|
|
126
|
+
Generates a default JSON usage example as a dictionary.
|
|
127
|
+
The provider argument is ignored, kept for API consistency.
|
|
129
128
|
"""
|
|
130
|
-
|
|
131
|
-
return
|
|
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}',
|
|
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.
|
|
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.
|
|
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
|
-
"""
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
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
|
autobyteus/tools/tool_meta.py
CHANGED
|
@@ -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
|
-
|
|
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
|
|
13
|
-
|
|
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
|
-
|
|
26
|
-
|
|
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
|