mcp-proxy-adapter 2.1.17__py3-none-any.whl → 3.0.1__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 (135) hide show
  1. examples/__init__.py +19 -0
  2. examples/anti_patterns/README.md +51 -0
  3. examples/anti_patterns/__init__.py +9 -0
  4. examples/anti_patterns/bad_design/README.md +72 -0
  5. examples/anti_patterns/bad_design/global_state.py +170 -0
  6. examples/anti_patterns/bad_design/monolithic_command.py +272 -0
  7. examples/basic_example/README.md +245 -0
  8. examples/basic_example/__init__.py +8 -0
  9. examples/basic_example/commands/__init__.py +5 -0
  10. examples/basic_example/commands/echo_command.py +95 -0
  11. examples/basic_example/commands/math_command.py +151 -0
  12. examples/basic_example/commands/time_command.py +152 -0
  13. examples/basic_example/config.json +25 -0
  14. examples/basic_example/docs/EN/README.md +177 -0
  15. examples/basic_example/docs/RU/README.md +177 -0
  16. examples/basic_example/server.py +151 -0
  17. examples/basic_example/tests/conftest.py +243 -0
  18. examples/commands/echo_command.py +52 -0
  19. examples/commands/echo_result.py +65 -0
  20. examples/commands/get_date_command.py +98 -0
  21. examples/commands/new_uuid4_command.py +91 -0
  22. examples/complete_example/Dockerfile +24 -0
  23. examples/complete_example/README.md +92 -0
  24. examples/complete_example/__init__.py +8 -0
  25. examples/complete_example/commands/__init__.py +5 -0
  26. examples/complete_example/commands/system_command.py +328 -0
  27. examples/complete_example/config.json +41 -0
  28. examples/complete_example/configs/config.dev.yaml +40 -0
  29. examples/complete_example/configs/config.docker.yaml +40 -0
  30. examples/complete_example/docker-compose.yml +35 -0
  31. examples/complete_example/requirements.txt +20 -0
  32. examples/complete_example/server.py +139 -0
  33. examples/minimal_example/README.md +65 -0
  34. examples/minimal_example/__init__.py +8 -0
  35. examples/minimal_example/config.json +14 -0
  36. examples/minimal_example/main.py +136 -0
  37. examples/minimal_example/simple_server.py +163 -0
  38. examples/minimal_example/tests/conftest.py +171 -0
  39. examples/minimal_example/tests/test_hello_command.py +111 -0
  40. examples/minimal_example/tests/test_integration.py +181 -0
  41. examples/server.py +69 -0
  42. examples/simple_server.py +128 -0
  43. examples/test_server.py +134 -0
  44. examples/tool_description_example.py +82 -0
  45. mcp_proxy_adapter/__init__.py +33 -1
  46. mcp_proxy_adapter/api/__init__.py +0 -0
  47. mcp_proxy_adapter/api/app.py +391 -0
  48. mcp_proxy_adapter/api/handlers.py +229 -0
  49. mcp_proxy_adapter/api/middleware/__init__.py +49 -0
  50. mcp_proxy_adapter/api/middleware/auth.py +146 -0
  51. mcp_proxy_adapter/api/middleware/base.py +79 -0
  52. mcp_proxy_adapter/api/middleware/error_handling.py +198 -0
  53. mcp_proxy_adapter/api/middleware/logging.py +96 -0
  54. mcp_proxy_adapter/api/middleware/performance.py +83 -0
  55. mcp_proxy_adapter/api/middleware/rate_limit.py +152 -0
  56. mcp_proxy_adapter/api/schemas.py +305 -0
  57. mcp_proxy_adapter/api/tool_integration.py +223 -0
  58. mcp_proxy_adapter/api/tools.py +198 -0
  59. mcp_proxy_adapter/commands/__init__.py +19 -0
  60. mcp_proxy_adapter/commands/base.py +301 -0
  61. mcp_proxy_adapter/commands/command_registry.py +231 -0
  62. mcp_proxy_adapter/commands/config_command.py +113 -0
  63. mcp_proxy_adapter/commands/health_command.py +136 -0
  64. mcp_proxy_adapter/commands/help_command.py +193 -0
  65. mcp_proxy_adapter/commands/result.py +215 -0
  66. mcp_proxy_adapter/config.py +195 -0
  67. mcp_proxy_adapter/core/__init__.py +0 -0
  68. mcp_proxy_adapter/core/errors.py +173 -0
  69. mcp_proxy_adapter/core/logging.py +205 -0
  70. mcp_proxy_adapter/core/utils.py +138 -0
  71. mcp_proxy_adapter/custom_openapi.py +125 -0
  72. mcp_proxy_adapter/openapi.py +403 -0
  73. mcp_proxy_adapter/py.typed +0 -0
  74. mcp_proxy_adapter/schemas/base_schema.json +114 -0
  75. mcp_proxy_adapter/schemas/openapi_schema.json +314 -0
  76. mcp_proxy_adapter/tests/__init__.py +0 -0
  77. mcp_proxy_adapter/tests/api/__init__.py +3 -0
  78. mcp_proxy_adapter/tests/api/test_cmd_endpoint.py +115 -0
  79. mcp_proxy_adapter/tests/api/test_middleware.py +336 -0
  80. mcp_proxy_adapter/tests/commands/__init__.py +3 -0
  81. mcp_proxy_adapter/tests/commands/test_config_command.py +211 -0
  82. mcp_proxy_adapter/tests/commands/test_echo_command.py +127 -0
  83. mcp_proxy_adapter/tests/commands/test_help_command.py +133 -0
  84. mcp_proxy_adapter/tests/conftest.py +131 -0
  85. mcp_proxy_adapter/tests/functional/__init__.py +3 -0
  86. mcp_proxy_adapter/tests/functional/test_api.py +235 -0
  87. mcp_proxy_adapter/tests/integration/__init__.py +3 -0
  88. mcp_proxy_adapter/tests/integration/test_cmd_integration.py +130 -0
  89. mcp_proxy_adapter/tests/integration/test_integration.py +255 -0
  90. mcp_proxy_adapter/tests/performance/__init__.py +3 -0
  91. mcp_proxy_adapter/tests/performance/test_performance.py +189 -0
  92. mcp_proxy_adapter/tests/stubs/__init__.py +10 -0
  93. mcp_proxy_adapter/tests/stubs/echo_command.py +104 -0
  94. mcp_proxy_adapter/tests/test_api_endpoints.py +271 -0
  95. mcp_proxy_adapter/tests/test_api_handlers.py +289 -0
  96. mcp_proxy_adapter/tests/test_base_command.py +123 -0
  97. mcp_proxy_adapter/tests/test_batch_requests.py +117 -0
  98. mcp_proxy_adapter/tests/test_command_registry.py +245 -0
  99. mcp_proxy_adapter/tests/test_config.py +127 -0
  100. mcp_proxy_adapter/tests/test_utils.py +65 -0
  101. mcp_proxy_adapter/tests/unit/__init__.py +3 -0
  102. mcp_proxy_adapter/tests/unit/test_base_command.py +130 -0
  103. mcp_proxy_adapter/tests/unit/test_config.py +217 -0
  104. mcp_proxy_adapter/version.py +3 -0
  105. mcp_proxy_adapter-3.0.1.dist-info/METADATA +200 -0
  106. mcp_proxy_adapter-3.0.1.dist-info/RECORD +109 -0
  107. {mcp_proxy_adapter-2.1.17.dist-info → mcp_proxy_adapter-3.0.1.dist-info}/top_level.txt +1 -0
  108. mcp_proxy_adapter/adapter.py +0 -697
  109. mcp_proxy_adapter/analyzers/__init__.py +0 -1
  110. mcp_proxy_adapter/analyzers/docstring_analyzer.py +0 -199
  111. mcp_proxy_adapter/analyzers/type_analyzer.py +0 -151
  112. mcp_proxy_adapter/dispatchers/__init__.py +0 -1
  113. mcp_proxy_adapter/dispatchers/base_dispatcher.py +0 -85
  114. mcp_proxy_adapter/dispatchers/json_rpc_dispatcher.py +0 -262
  115. mcp_proxy_adapter/examples/analyze_config.py +0 -141
  116. mcp_proxy_adapter/examples/basic_integration.py +0 -155
  117. mcp_proxy_adapter/examples/docstring_and_schema_example.py +0 -69
  118. mcp_proxy_adapter/examples/extension_example.py +0 -72
  119. mcp_proxy_adapter/examples/help_best_practices.py +0 -67
  120. mcp_proxy_adapter/examples/help_usage.py +0 -64
  121. mcp_proxy_adapter/examples/mcp_proxy_client.py +0 -131
  122. mcp_proxy_adapter/examples/openapi_server.py +0 -383
  123. mcp_proxy_adapter/examples/project_structure_example.py +0 -47
  124. mcp_proxy_adapter/examples/testing_example.py +0 -64
  125. mcp_proxy_adapter/models.py +0 -47
  126. mcp_proxy_adapter/registry.py +0 -439
  127. mcp_proxy_adapter/schema.py +0 -257
  128. mcp_proxy_adapter/testing_utils.py +0 -112
  129. mcp_proxy_adapter/validators/__init__.py +0 -1
  130. mcp_proxy_adapter/validators/docstring_validator.py +0 -75
  131. mcp_proxy_adapter/validators/metadata_validator.py +0 -76
  132. mcp_proxy_adapter-2.1.17.dist-info/METADATA +0 -376
  133. mcp_proxy_adapter-2.1.17.dist-info/RECORD +0 -30
  134. {mcp_proxy_adapter-2.1.17.dist-info → mcp_proxy_adapter-3.0.1.dist-info}/WHEEL +0 -0
  135. {mcp_proxy_adapter-2.1.17.dist-info → mcp_proxy_adapter-3.0.1.dist-info}/licenses/LICENSE +0 -0
@@ -0,0 +1,198 @@
1
+ """
2
+ Модуль с реализацией инструментов API для внешних систем.
3
+
4
+ Этот модуль содержит классы инструментов API, которые могут быть
5
+ интегрированы с внешними системами для выполнения команд микросервиса.
6
+ """
7
+
8
+ from typing import Any, Dict, Optional, Union, List
9
+ import json
10
+ import logging
11
+
12
+ from mcp_proxy_adapter.api.tool_integration import ToolIntegration
13
+ from mcp_proxy_adapter.commands.command_registry import registry
14
+ from mcp_proxy_adapter.core.errors import NotFoundError, InvalidParamsError
15
+
16
+ logger = logging.getLogger(__name__)
17
+
18
+
19
+ class TSTCommandExecutor:
20
+ """
21
+ Инструмент для выполнения команд через JSON-RPC протокол на сервере проекта.
22
+
23
+ Этот класс предоставляет функциональность для выполнения команд микросервиса
24
+ через внешний интерфейс TST (Tool-System-Transport).
25
+ """
26
+
27
+ name = "tst_execute_command"
28
+ description = "Выполняет команду через JSON-RPC протокол."
29
+
30
+ @classmethod
31
+ async def execute(cls, command: str, params: Optional[Dict[str, Any]] = None) -> Dict[str, Any]:
32
+ """
33
+ Выполняет команду с указанными параметрами.
34
+
35
+ Args:
36
+ command: Имя команды для выполнения
37
+ params: Параметры команды (опционально)
38
+
39
+ Returns:
40
+ Результат выполнения команды
41
+
42
+ Raises:
43
+ NotFoundError: Если команда не найдена
44
+ InvalidParamsError: Если переданы некорректные параметры
45
+ """
46
+ if not params:
47
+ params = {}
48
+
49
+ logger.info(f"Executing command via TST: {command}, params: {params}")
50
+
51
+ try:
52
+ # Проверяем существование команды
53
+ if not registry.command_exists(command):
54
+ raise NotFoundError(f"Команда '{command}' не найдена")
55
+
56
+ # Получаем класс команды
57
+ command_class = registry.get_command(command)
58
+
59
+ # Выполняем команду
60
+ result = await command_class.run(**params)
61
+
62
+ # Возвращаем результат
63
+ return result.to_dict()
64
+ except NotFoundError as e:
65
+ logger.error(f"Command not found: {command}")
66
+ raise
67
+ except Exception as e:
68
+ logger.exception(f"Error executing command {command}: {e}")
69
+ raise
70
+
71
+ @classmethod
72
+ def get_schema(cls) -> Dict[str, Any]:
73
+ """
74
+ Возвращает схему инструмента в формате OpenAPI.
75
+
76
+ Returns:
77
+ Словарь со схемой инструмента
78
+ """
79
+ return ToolIntegration.generate_tool_schema(cls.name, registry, cls.description)
80
+
81
+ @classmethod
82
+ def get_description(cls, format: str = "json") -> Union[Dict[str, Any], str]:
83
+ """
84
+ Возвращает полное описание инструмента в указанном формате.
85
+
86
+ Args:
87
+ format: Формат описания (json, markdown, html)
88
+
89
+ Returns:
90
+ Описание инструмента в указанном формате
91
+ """
92
+ if format.lower() == "json":
93
+ # Получаем базовое описание инструмента
94
+ base_description = ToolIntegration.generate_tool_schema(cls.name, registry, cls.description)
95
+
96
+ # Добавляем дополнительную информацию
97
+ base_description["examples"] = cls._generate_examples()
98
+ base_description["error_codes"] = cls._generate_error_codes()
99
+
100
+ return base_description
101
+ elif format.lower() in ["markdown", "text", "html"]:
102
+ return ToolIntegration.generate_tool_documentation(cls.name, registry, format)
103
+ else:
104
+ # По умолчанию возвращаем JSON формат
105
+ return ToolIntegration.generate_tool_schema(cls.name, registry, cls.description)
106
+
107
+ @classmethod
108
+ def _generate_examples(cls) -> List[Dict[str, Any]]:
109
+ """
110
+ Генерирует примеры использования инструмента.
111
+
112
+ Returns:
113
+ Список примеров использования
114
+ """
115
+ examples = []
116
+
117
+ # Получаем метаданные всех команд
118
+ all_metadata = registry.get_all_metadata()
119
+
120
+ # Добавляем по одному примеру для каждой команды
121
+ for cmd_name, metadata in all_metadata.items():
122
+ if metadata.get("examples"):
123
+ # Берем первый пример из метаданных
124
+ example = metadata["examples"][0]
125
+
126
+ # Формируем пример использования инструмента
127
+ examples.append({
128
+ "command": cls.name,
129
+ "params": {
130
+ "command": example.get("command", cmd_name),
131
+ "params": example.get("params", {})
132
+ },
133
+ "description": f"Выполнение команды {cmd_name}"
134
+ })
135
+
136
+ return examples
137
+
138
+ @classmethod
139
+ def _generate_error_codes(cls) -> Dict[str, str]:
140
+ """
141
+ Генерирует словарь возможных кодов ошибок.
142
+
143
+ Returns:
144
+ Словарь с кодами ошибок и их описаниями
145
+ """
146
+ return {
147
+ "-32600": "Некорректный запрос",
148
+ "-32601": "Команда не найдена",
149
+ "-32602": "Некорректные параметры",
150
+ "-32603": "Внутренняя ошибка",
151
+ "-32000": "Ошибка выполнения команды"
152
+ }
153
+
154
+
155
+ # Экспортируем доступные инструменты API
156
+ available_tools = {
157
+ TSTCommandExecutor.name: TSTCommandExecutor
158
+ }
159
+
160
+
161
+ def get_tool_description(tool_name: str, format: str = "json") -> Union[Dict[str, Any], str]:
162
+ """
163
+ Получает описание инструмента API по имени.
164
+
165
+ Args:
166
+ tool_name: Имя инструмента API
167
+ format: Формат описания (json, markdown, html)
168
+
169
+ Returns:
170
+ Описание инструмента в указанном формате
171
+
172
+ Raises:
173
+ NotFoundError: Если инструмент не найден
174
+ """
175
+ if tool_name in available_tools:
176
+ return available_tools[tool_name].get_description(format)
177
+ else:
178
+ raise NotFoundError(f"Инструмент '{tool_name}' не найден")
179
+
180
+
181
+ async def execute_tool(tool_name: str, **params) -> Dict[str, Any]:
182
+ """
183
+ Выполняет инструмент API с указанными параметрами.
184
+
185
+ Args:
186
+ tool_name: Имя инструмента API
187
+ **params: Параметры инструмента
188
+
189
+ Returns:
190
+ Результат выполнения инструмента
191
+
192
+ Raises:
193
+ NotFoundError: Если инструмент не найден
194
+ """
195
+ if tool_name in available_tools:
196
+ return await available_tools[tool_name].execute(**params)
197
+ else:
198
+ raise NotFoundError(f"Инструмент '{tool_name}' не найден")
@@ -0,0 +1,19 @@
1
+ """
2
+ Package with command implementation.
3
+ """
4
+
5
+ from mcp_proxy_adapter.commands.base import Command
6
+ from mcp_proxy_adapter.commands.result import CommandResult, SuccessResult, ErrorResult
7
+ from mcp_proxy_adapter.commands.command_registry import registry, CommandRegistry
8
+
9
+ # Automatically discover and register commands
10
+ registry.discover_commands()
11
+
12
+ __all__ = [
13
+ "Command",
14
+ "CommandResult",
15
+ "SuccessResult",
16
+ "ErrorResult",
17
+ "registry",
18
+ "CommandRegistry"
19
+ ]
@@ -0,0 +1,301 @@
1
+ """
2
+ Module with base command class.
3
+ """
4
+
5
+ import inspect
6
+ from abc import ABC, abstractmethod
7
+ from typing import Any, ClassVar, Dict, List, Optional, Type, TypeVar, Union
8
+
9
+ from mcp_proxy_adapter.commands.result import CommandResult, ErrorResult, SuccessResult
10
+ from mcp_proxy_adapter.core.errors import (
11
+ ValidationError, CommandError, InternalError, InvalidParamsError,
12
+ NotFoundError, TimeoutError
13
+ )
14
+ from mcp_proxy_adapter.core.logging import logger
15
+
16
+ T = TypeVar("T", bound=CommandResult)
17
+
18
+
19
+ class Command(ABC):
20
+ """
21
+ Base abstract class for all commands.
22
+ """
23
+
24
+ # Command name for registration
25
+ name: ClassVar[str]
26
+ # Result class
27
+ result_class: ClassVar[Type[CommandResult]]
28
+
29
+ @abstractmethod
30
+ async def execute(self, **kwargs) -> CommandResult:
31
+ """
32
+ Executes command with given parameters.
33
+
34
+ Args:
35
+ **kwargs: Command parameters.
36
+
37
+ Returns:
38
+ Command execution result.
39
+ """
40
+ pass
41
+
42
+ @classmethod
43
+ def get_schema(cls) -> Dict[str, Any]:
44
+ """
45
+ Returns JSON schema for command parameters validation.
46
+ This method should be overridden in child classes.
47
+
48
+ Returns:
49
+ Dictionary with JSON schema.
50
+ """
51
+ # Default base schema that can be overridden
52
+ return {
53
+ "type": "object",
54
+ "properties": {},
55
+ "additionalProperties": False
56
+ }
57
+
58
+ @classmethod
59
+ def get_result_schema(cls) -> Dict[str, Any]:
60
+ """
61
+ Returns JSON schema for command result validation.
62
+
63
+ Returns:
64
+ Dictionary with JSON schema.
65
+ """
66
+ if hasattr(cls, "result_class") and cls.result_class:
67
+ return cls.result_class.get_schema()
68
+ return {}
69
+
70
+ @classmethod
71
+ def validate_params(cls, params: Dict[str, Any]) -> Dict[str, Any]:
72
+ """
73
+ Validates command parameters before execution.
74
+ This method can be overridden in child classes for custom validation.
75
+
76
+ Args:
77
+ params: Parameters to validate.
78
+
79
+ Returns:
80
+ Validated parameters.
81
+
82
+ Raises:
83
+ ValidationError: If parameters failed validation.
84
+ """
85
+ # In base implementation, simply return parameters without validation
86
+ # In real implementation, jsonschema or pydantic will be used here
87
+ return params
88
+
89
+ @classmethod
90
+ async def run(cls, **kwargs) -> CommandResult:
91
+ """
92
+ Runs command with parameters validation.
93
+
94
+ Args:
95
+ **kwargs: Command parameters.
96
+
97
+ Returns:
98
+ Command execution result.
99
+ """
100
+ try:
101
+ logger.debug(f"Running command {cls.__name__} with params: {kwargs}")
102
+
103
+ # Parameters validation
104
+ validated_params = cls.validate_params(kwargs)
105
+
106
+ # Create command instance
107
+ command = cls()
108
+
109
+ # Execute command
110
+ result = await command.execute(**validated_params)
111
+
112
+ logger.debug(f"Command {cls.__name__} executed successfully")
113
+ return result
114
+ except ValidationError as e:
115
+ # Ошибка валидации параметров
116
+ logger.error(f"Validation error in command {cls.__name__}: {e}")
117
+ return ErrorResult(
118
+ message=str(e),
119
+ code=e.code,
120
+ details=e.data
121
+ )
122
+ except InvalidParamsError as e:
123
+ # Ошибка в параметрах команды
124
+ logger.error(f"Invalid parameters error in command {cls.__name__}: {e}")
125
+ return ErrorResult(
126
+ message=str(e),
127
+ code=e.code,
128
+ details=e.data
129
+ )
130
+ except NotFoundError as e:
131
+ # Ресурс не найден
132
+ logger.error(f"Resource not found error in command {cls.__name__}: {e}")
133
+ return ErrorResult(
134
+ message=str(e),
135
+ code=e.code,
136
+ details=e.data
137
+ )
138
+ except TimeoutError as e:
139
+ # Превышено время ожидания
140
+ logger.error(f"Timeout error in command {cls.__name__}: {e}")
141
+ return ErrorResult(
142
+ message=str(e),
143
+ code=e.code,
144
+ details=e.data
145
+ )
146
+ except CommandError as e:
147
+ # Ошибка выполнения команды
148
+ logger.error(f"Command error in {cls.__name__}: {e}")
149
+ return ErrorResult(
150
+ message=str(e),
151
+ code=e.code,
152
+ details=e.data
153
+ )
154
+ except Exception as e:
155
+ # Непредвиденная ошибка
156
+ logger.exception(f"Unexpected error executing command {cls.__name__}: {e}")
157
+ internal_error = InternalError(f"Command execution error: {str(e)}")
158
+ return ErrorResult(
159
+ message=internal_error.message,
160
+ code=internal_error.code,
161
+ details={"original_error": str(e)}
162
+ )
163
+
164
+ @classmethod
165
+ def get_param_info(cls) -> Dict[str, Dict[str, Any]]:
166
+ """
167
+ Gets information about execute method parameters.
168
+
169
+ Returns:
170
+ Dictionary with parameters information.
171
+ """
172
+ signature = inspect.signature(cls.execute)
173
+ params = {}
174
+
175
+ for name, param in signature.parameters.items():
176
+ if name == "self":
177
+ continue
178
+
179
+ param_info = {
180
+ "name": name,
181
+ "required": param.default == inspect.Parameter.empty
182
+ }
183
+
184
+ if param.annotation != inspect.Parameter.empty:
185
+ param_info["type"] = str(param.annotation)
186
+
187
+ if param.default != inspect.Parameter.empty:
188
+ param_info["default"] = param.default
189
+
190
+ params[name] = param_info
191
+
192
+ return params
193
+
194
+ @classmethod
195
+ def get_metadata(cls) -> Dict[str, Any]:
196
+ """
197
+ Returns complete metadata about the command.
198
+
199
+ Provides a single access point to all command metadata.
200
+
201
+ Returns:
202
+ Dict with command metadata
203
+ """
204
+ # Get and format docstring
205
+ doc = cls.__doc__ or ""
206
+ description = inspect.cleandoc(doc) if doc else ""
207
+
208
+ # Extract first line for summary
209
+ summary = description.split("\n")[0] if description else ""
210
+
211
+ # Get parameters information
212
+ param_info = cls.get_param_info()
213
+
214
+ # Generate examples based on parameters
215
+ examples = cls._generate_examples(param_info)
216
+
217
+ return {
218
+ "name": cls.name,
219
+ "summary": summary,
220
+ "description": description,
221
+ "params": param_info,
222
+ "examples": examples,
223
+ "schema": cls.get_schema(),
224
+ "result_schema": cls.get_result_schema(),
225
+ "result_class": cls.result_class.__name__ if hasattr(cls, "result_class") else None,
226
+ }
227
+
228
+ @classmethod
229
+ def _generate_examples(cls, params: Dict[str, Dict[str, Any]]) -> List[Dict[str, Any]]:
230
+ """
231
+ Generates usage examples of the command based on its parameters.
232
+
233
+ Args:
234
+ params: Information about command parameters
235
+
236
+ Returns:
237
+ List of examples
238
+ """
239
+ examples = []
240
+
241
+ # Simple example without parameters, if all parameters are optional
242
+ if not any(param.get("required", False) for param in params.values()):
243
+ examples.append({
244
+ "command": cls.name,
245
+ "description": f"Call {cls.name} command without parameters"
246
+ })
247
+
248
+ # Example with all required parameters
249
+ required_params = {k: v for k, v in params.items() if v.get("required", False)}
250
+ if required_params:
251
+ example_params = {}
252
+ for param_name, param_info in required_params.items():
253
+ # Generate suitable example value based on parameter type
254
+ param_type = param_info.get("type", "")
255
+ if "str" in param_type.lower():
256
+ example_params[param_name] = f"example_{param_name}"
257
+ elif "int" in param_type.lower():
258
+ example_params[param_name] = 123
259
+ elif "float" in param_type.lower():
260
+ example_params[param_name] = 123.45
261
+ elif "bool" in param_type.lower():
262
+ example_params[param_name] = True
263
+ else:
264
+ example_params[param_name] = f"value_for_{param_name}"
265
+
266
+ examples.append({
267
+ "command": cls.name,
268
+ "params": example_params,
269
+ "description": f"Call {cls.name} command with required parameters"
270
+ })
271
+
272
+ # Add example with all parameters, if there are optional ones
273
+ optional_params = {k: v for k, v in params.items() if not v.get("required", False)}
274
+ if optional_params and required_params:
275
+ full_example_params = dict(example_params) if 'example_params' in locals() else {}
276
+
277
+ for param_name, param_info in optional_params.items():
278
+ # Get default value or generate suitable example
279
+ if "default" in param_info:
280
+ full_example_params[param_name] = param_info["default"]
281
+ else:
282
+ # Generate suitable example value based on parameter type
283
+ param_type = param_info.get("type", "")
284
+ if "str" in param_type.lower():
285
+ full_example_params[param_name] = f"optional_{param_name}"
286
+ elif "int" in param_type.lower():
287
+ full_example_params[param_name] = 456
288
+ elif "float" in param_type.lower():
289
+ full_example_params[param_name] = 45.67
290
+ elif "bool" in param_type.lower():
291
+ full_example_params[param_name] = False
292
+ else:
293
+ full_example_params[param_name] = f"optional_value_for_{param_name}"
294
+
295
+ examples.append({
296
+ "command": cls.name,
297
+ "params": full_example_params,
298
+ "description": f"Call {cls.name} command with all parameters"
299
+ })
300
+
301
+ return examples