autobyteus 1.1.0__py3-none-any.whl → 1.1.2__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- autobyteus/agent/bootstrap_steps/agent_bootstrapper.py +1 -1
- autobyteus/agent/bootstrap_steps/agent_runtime_queue_initialization_step.py +1 -1
- autobyteus/agent/bootstrap_steps/base_bootstrap_step.py +1 -1
- autobyteus/agent/bootstrap_steps/system_prompt_processing_step.py +1 -1
- autobyteus/agent/bootstrap_steps/workspace_context_initialization_step.py +1 -1
- autobyteus/agent/context/__init__.py +0 -5
- autobyteus/agent/context/agent_config.py +6 -2
- autobyteus/agent/context/agent_context.py +2 -5
- autobyteus/agent/context/agent_phase_manager.py +105 -5
- autobyteus/agent/context/agent_runtime_state.py +2 -2
- autobyteus/agent/context/phases.py +2 -0
- autobyteus/agent/events/__init__.py +0 -11
- autobyteus/agent/events/agent_events.py +0 -37
- autobyteus/agent/events/notifiers.py +25 -7
- autobyteus/agent/events/worker_event_dispatcher.py +1 -1
- autobyteus/agent/factory/agent_factory.py +6 -2
- autobyteus/agent/group/agent_group.py +16 -7
- autobyteus/agent/handlers/approved_tool_invocation_event_handler.py +28 -14
- autobyteus/agent/handlers/lifecycle_event_logger.py +1 -1
- autobyteus/agent/handlers/llm_complete_response_received_event_handler.py +4 -2
- autobyteus/agent/handlers/tool_invocation_request_event_handler.py +40 -15
- autobyteus/agent/handlers/tool_result_event_handler.py +12 -7
- autobyteus/agent/hooks/__init__.py +7 -0
- autobyteus/agent/hooks/base_phase_hook.py +11 -2
- autobyteus/agent/hooks/hook_definition.py +36 -0
- autobyteus/agent/hooks/hook_meta.py +37 -0
- autobyteus/agent/hooks/hook_registry.py +118 -0
- autobyteus/agent/input_processor/base_user_input_processor.py +6 -3
- autobyteus/agent/input_processor/passthrough_input_processor.py +2 -1
- autobyteus/agent/input_processor/processor_meta.py +1 -1
- autobyteus/agent/input_processor/processor_registry.py +19 -0
- autobyteus/agent/llm_response_processor/base_processor.py +6 -3
- autobyteus/agent/llm_response_processor/processor_meta.py +1 -1
- autobyteus/agent/llm_response_processor/processor_registry.py +19 -0
- autobyteus/agent/llm_response_processor/provider_aware_tool_usage_processor.py +2 -1
- autobyteus/agent/message/context_file_type.py +2 -3
- autobyteus/agent/phases/__init__.py +18 -0
- autobyteus/agent/phases/discover.py +52 -0
- autobyteus/agent/phases/manager.py +265 -0
- autobyteus/agent/phases/phase_enum.py +49 -0
- autobyteus/agent/phases/transition_decorator.py +40 -0
- autobyteus/agent/phases/transition_info.py +33 -0
- autobyteus/agent/remote_agent.py +1 -1
- autobyteus/agent/runtime/agent_runtime.py +5 -10
- autobyteus/agent/runtime/agent_worker.py +62 -19
- autobyteus/agent/streaming/agent_event_stream.py +58 -5
- autobyteus/agent/streaming/stream_event_payloads.py +24 -13
- autobyteus/agent/streaming/stream_events.py +14 -11
- autobyteus/agent/system_prompt_processor/base_processor.py +6 -3
- autobyteus/agent/system_prompt_processor/processor_meta.py +1 -1
- autobyteus/agent/system_prompt_processor/tool_manifest_injector_processor.py +45 -31
- autobyteus/agent/tool_invocation.py +29 -3
- autobyteus/agent/utils/wait_for_idle.py +1 -1
- autobyteus/agent/workspace/__init__.py +2 -0
- autobyteus/agent/workspace/base_workspace.py +33 -11
- autobyteus/agent/workspace/workspace_config.py +160 -0
- autobyteus/agent/workspace/workspace_definition.py +36 -0
- autobyteus/agent/workspace/workspace_meta.py +37 -0
- autobyteus/agent/workspace/workspace_registry.py +72 -0
- autobyteus/cli/__init__.py +4 -3
- autobyteus/cli/agent_cli.py +25 -207
- autobyteus/cli/cli_display.py +205 -0
- autobyteus/events/event_manager.py +2 -1
- autobyteus/events/event_types.py +3 -1
- autobyteus/llm/api/autobyteus_llm.py +2 -12
- autobyteus/llm/api/deepseek_llm.py +11 -173
- autobyteus/llm/api/grok_llm.py +11 -172
- autobyteus/llm/api/kimi_llm.py +24 -0
- autobyteus/llm/api/mistral_llm.py +4 -4
- autobyteus/llm/api/ollama_llm.py +2 -2
- autobyteus/llm/api/openai_compatible_llm.py +193 -0
- autobyteus/llm/api/openai_llm.py +11 -139
- autobyteus/llm/extensions/token_usage_tracking_extension.py +11 -1
- autobyteus/llm/llm_factory.py +168 -42
- autobyteus/llm/models.py +25 -29
- autobyteus/llm/ollama_provider.py +6 -2
- autobyteus/llm/ollama_provider_resolver.py +44 -0
- autobyteus/llm/providers.py +1 -0
- autobyteus/llm/token_counter/kimi_token_counter.py +24 -0
- autobyteus/llm/token_counter/token_counter_factory.py +3 -0
- autobyteus/llm/utils/messages.py +3 -3
- autobyteus/tools/__init__.py +2 -0
- autobyteus/tools/base_tool.py +7 -1
- autobyteus/tools/functional_tool.py +20 -5
- autobyteus/tools/mcp/call_handlers/stdio_handler.py +15 -1
- autobyteus/tools/mcp/config_service.py +106 -127
- autobyteus/tools/mcp/registrar.py +247 -59
- autobyteus/tools/mcp/types.py +5 -3
- autobyteus/tools/registry/tool_definition.py +8 -1
- autobyteus/tools/registry/tool_registry.py +18 -0
- autobyteus/tools/tool_category.py +11 -0
- autobyteus/tools/tool_meta.py +3 -1
- autobyteus/tools/tool_state.py +20 -0
- autobyteus/tools/usage/parsers/_json_extractor.py +99 -0
- autobyteus/tools/usage/parsers/default_json_tool_usage_parser.py +46 -77
- autobyteus/tools/usage/parsers/default_xml_tool_usage_parser.py +87 -96
- autobyteus/tools/usage/parsers/gemini_json_tool_usage_parser.py +37 -47
- autobyteus/tools/usage/parsers/openai_json_tool_usage_parser.py +112 -113
- {autobyteus-1.1.0.dist-info → autobyteus-1.1.2.dist-info}/METADATA +13 -12
- {autobyteus-1.1.0.dist-info → autobyteus-1.1.2.dist-info}/RECORD +103 -82
- {autobyteus-1.1.0.dist-info → autobyteus-1.1.2.dist-info}/WHEEL +0 -0
- {autobyteus-1.1.0.dist-info → autobyteus-1.1.2.dist-info}/licenses/LICENSE +0 -0
- {autobyteus-1.1.0.dist-info → autobyteus-1.1.2.dist-info}/top_level.txt +0 -0
|
@@ -23,7 +23,8 @@ class McpConfigService(metaclass=SingletonMeta):
|
|
|
23
23
|
self._configs: Dict[str, BaseMcpConfig] = {}
|
|
24
24
|
logger.info("McpConfigService initialized.")
|
|
25
25
|
|
|
26
|
-
|
|
26
|
+
@staticmethod
|
|
27
|
+
def _parse_transport_type(type_str: str, server_identifier: str) -> McpTransportType:
|
|
27
28
|
"""Parses string to McpTransportType enum."""
|
|
28
29
|
try:
|
|
29
30
|
return McpTransportType(type_str.lower())
|
|
@@ -34,21 +35,19 @@ class McpConfigService(metaclass=SingletonMeta):
|
|
|
34
35
|
f"Valid types are: {valid_types}."
|
|
35
36
|
)
|
|
36
37
|
|
|
37
|
-
|
|
38
|
+
@staticmethod
|
|
39
|
+
def _create_specific_config(server_id: str, transport_type: McpTransportType, config_data: Dict[str, Any]) -> BaseMcpConfig:
|
|
38
40
|
"""
|
|
39
41
|
Creates a specific McpServerConfig (Stdio, Sse, StreamableHttp) based on transport_type.
|
|
40
42
|
The 'server_id' is injected.
|
|
41
43
|
Parameters from nested structures like 'stdio_params' are un-nested.
|
|
42
44
|
"""
|
|
43
|
-
# Start with base parameters that can be at the top level of config_data
|
|
44
45
|
constructor_params = {'server_id': server_id}
|
|
45
46
|
|
|
46
|
-
# Explicitly copy known BaseMcpConfig fields from config_data if they exist
|
|
47
47
|
for base_key in ['enabled', 'tool_name_prefix']:
|
|
48
48
|
if base_key in config_data:
|
|
49
49
|
constructor_params[base_key] = config_data[base_key]
|
|
50
50
|
|
|
51
|
-
# Define keys for nested transport-specific parameters
|
|
52
51
|
transport_specific_params_key_map = {
|
|
53
52
|
McpTransportType.STDIO: "stdio_params",
|
|
54
53
|
McpTransportType.SSE: "sse_params",
|
|
@@ -60,39 +59,19 @@ class McpConfigService(metaclass=SingletonMeta):
|
|
|
60
59
|
specific_params_dict = config_data.get(params_key, {})
|
|
61
60
|
if not isinstance(specific_params_dict, dict):
|
|
62
61
|
raise ValueError(f"'{params_key}' for server '{server_id}' must be a dictionary, got {type(specific_params_dict)}.")
|
|
63
|
-
# Merge extracted specific params into constructor_params
|
|
64
|
-
# This allows specific params (e.g. 'command') to be defined inside the nested dict
|
|
65
62
|
constructor_params.update(specific_params_dict)
|
|
66
63
|
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
# or an item from the list of configs.
|
|
72
|
-
# So, 'transport_type' and 'stdio_params' (etc.) will be keys in it.
|
|
64
|
+
constructor_params.pop(transport_specific_params_key_map.get(McpTransportType.STDIO), None)
|
|
65
|
+
constructor_params.pop(transport_specific_params_key_map.get(McpTransportType.SSE), None)
|
|
66
|
+
constructor_params.pop(transport_specific_params_key_map.get(McpTransportType.STREAMABLE_HTTP), None)
|
|
67
|
+
constructor_params.pop('transport_type', None)
|
|
73
68
|
|
|
74
|
-
# Clean up params_for_constructor by removing original nested dict keys and transport_type
|
|
75
|
-
if transport_type in transport_specific_params_key_map:
|
|
76
|
-
constructor_params.pop(transport_specific_params_key_map[transport_type], None)
|
|
77
|
-
constructor_params.pop('transport_type', None) # From original config_data if it was spread
|
|
78
|
-
# Actually, config_data doesn't have server_id yet.
|
|
79
|
-
# server_id is added to constructor_params at the start.
|
|
80
|
-
# transport_type is not added to constructor_params from config_data.
|
|
81
|
-
|
|
82
|
-
# This part ensures any other top-level keys in config_data that are valid for the
|
|
83
|
-
# specific config class (but not 'enabled', 'tool_name_prefix', or the nested param dict key itself)
|
|
84
|
-
# are also included.
|
|
85
|
-
# Example: if StdioMcpServerConfig had a field 'priority' that could be in config_data top-level.
|
|
86
69
|
other_top_level_keys_to_copy = {
|
|
87
70
|
k: v for k, v in config_data.items()
|
|
88
|
-
if k not in ['enabled', 'tool_name_prefix', 'transport_type'
|
|
89
|
-
transport_specific_params_key_map.get(McpTransportType.STDIO),
|
|
90
|
-
transport_specific_params_key_map.get(McpTransportType.SSE),
|
|
91
|
-
transport_specific_params_key_map.get(McpTransportType.STREAMABLE_HTTP)]
|
|
71
|
+
if k not in ['enabled', 'tool_name_prefix', 'transport_type'] and k not in transport_specific_params_key_map.values()
|
|
92
72
|
}
|
|
93
73
|
constructor_params.update(other_top_level_keys_to_copy)
|
|
94
74
|
|
|
95
|
-
|
|
96
75
|
try:
|
|
97
76
|
if transport_type == McpTransportType.STDIO:
|
|
98
77
|
return StdioMcpServerConfig(**constructor_params)
|
|
@@ -101,33 +80,77 @@ class McpConfigService(metaclass=SingletonMeta):
|
|
|
101
80
|
elif transport_type == McpTransportType.STREAMABLE_HTTP:
|
|
102
81
|
return StreamableHttpMcpServerConfig(**constructor_params)
|
|
103
82
|
else:
|
|
104
|
-
|
|
105
|
-
raise ValueError(f"Unsupported McpTransportType '{transport_type}' for server '{server_id}'. Cannot create specific config.")
|
|
83
|
+
raise ValueError(f"Unsupported McpTransportType '{transport_type}' for server '{server_id}'.")
|
|
106
84
|
except TypeError as e:
|
|
107
85
|
logger.error(f"TypeError creating config for server '{server_id}' with transport '{transport_type}'. "
|
|
108
86
|
f"Params: {constructor_params}. Error: {e}", exc_info=True)
|
|
109
87
|
raise ValueError(f"Failed to create config for server '{server_id}' due to incompatible parameters for {transport_type.name} config: {e}")
|
|
110
88
|
|
|
89
|
+
@staticmethod
|
|
90
|
+
def parse_mcp_config_dict(config_dict: Dict[str, Any]) -> BaseMcpConfig:
|
|
91
|
+
"""
|
|
92
|
+
Parses a dictionary representing a single MCP server configuration into a
|
|
93
|
+
validated BaseMcpConfig dataclass object.
|
|
94
|
+
The dictionary is expected to have a single top-level key which is the server_id.
|
|
95
|
+
"""
|
|
96
|
+
if not isinstance(config_dict, dict) or len(config_dict) != 1:
|
|
97
|
+
raise ValueError("Input must be a dictionary with a single top-level key representing the server_id.")
|
|
98
|
+
|
|
99
|
+
server_id = next(iter(config_dict))
|
|
100
|
+
config_data = config_dict[server_id]
|
|
111
101
|
|
|
112
|
-
|
|
102
|
+
if not isinstance(config_data, dict):
|
|
103
|
+
raise ValueError(f"Configuration for server '{server_id}' must be a dictionary.")
|
|
104
|
+
|
|
105
|
+
transport_type_str = config_data.get('transport_type')
|
|
106
|
+
if not transport_type_str:
|
|
107
|
+
raise ValueError(f"Config data for server '{server_id}' is missing 'transport_type' field.")
|
|
108
|
+
|
|
109
|
+
transport_type = McpConfigService._parse_transport_type(transport_type_str, server_id)
|
|
110
|
+
return McpConfigService._create_specific_config(server_id, transport_type, config_data)
|
|
111
|
+
|
|
112
|
+
def add_config(self, config_object: BaseMcpConfig) -> BaseMcpConfig:
|
|
113
|
+
"""Adds or updates a single, pre-instantiated MCP server configuration object."""
|
|
114
|
+
if not isinstance(config_object, BaseMcpConfig):
|
|
115
|
+
raise TypeError(f"Unsupported input type for add_config: {type(config_object)}. "
|
|
116
|
+
"Expected a BaseMcpConfig subclass object (e.g., StdioMcpServerConfig).")
|
|
117
|
+
|
|
118
|
+
if config_object.server_id in self._configs:
|
|
119
|
+
logger.warning(f"Overwriting existing MCP config with server_id '{config_object.server_id}'.")
|
|
120
|
+
|
|
121
|
+
self._configs[config_object.server_id] = config_object
|
|
122
|
+
logger.info(f"Successfully added/updated {type(config_object).__name__} for server_id '{config_object.server_id}'. "
|
|
123
|
+
f"Total unique configs stored: {len(self._configs)}.")
|
|
124
|
+
return config_object
|
|
125
|
+
|
|
126
|
+
def load_config(self, config_dict: Dict[str, Any]) -> BaseMcpConfig:
|
|
113
127
|
"""
|
|
114
|
-
|
|
115
|
-
Source can be:
|
|
116
|
-
1. A file path (str) to a JSON file. The JSON file can contain:
|
|
117
|
-
a. A list of MCP server configuration dictionaries. Each dict must include "server_id" and "transport_type".
|
|
118
|
-
b. A dictionary where keys are server IDs and values are configurations. Each value dict must include "transport_type".
|
|
119
|
-
The dictionary key is used as the McpConfig 'server_id'.
|
|
120
|
-
2. A direct list of MCP server configuration dictionaries (List[Dict[str, Any]]).
|
|
121
|
-
Each dictionary in the list must have "server_id" and "transport_type".
|
|
122
|
-
3. A direct dictionary where keys are server IDs and values are configurations (Dict[str, Any]).
|
|
123
|
-
Each value dict must include "transport_type". The dictionary key is used as the McpConfig 'server_id'.
|
|
128
|
+
Parses a single raw configuration dictionary and adds it to the service.
|
|
124
129
|
|
|
125
130
|
Args:
|
|
126
|
-
|
|
131
|
+
config_dict: A dictionary representing a single server config,
|
|
132
|
+
with the server_id as the top-level key.
|
|
133
|
+
|
|
134
|
+
Returns:
|
|
135
|
+
The successfully parsed and added McpServerConfig object.
|
|
136
|
+
"""
|
|
137
|
+
config_object = self.parse_mcp_config_dict(config_dict)
|
|
138
|
+
return self.add_config(config_object)
|
|
127
139
|
|
|
140
|
+
|
|
141
|
+
def load_configs(self, source: Union[str, List[Dict[str, Any]], Dict[str, Any]]) -> List[BaseMcpConfig]:
|
|
142
|
+
"""
|
|
143
|
+
Loads multiple MCP configurations from a source, parsing and adding them.
|
|
144
|
+
This will overwrite any existing configurations with the same server_id.
|
|
145
|
+
|
|
146
|
+
Args:
|
|
147
|
+
source: The data source. Can be:
|
|
148
|
+
1. A file path (str) to a JSON file.
|
|
149
|
+
2. A list of MCP server configuration dictionaries.
|
|
150
|
+
3. A dictionary of configurations, keyed by server_id.
|
|
151
|
+
|
|
128
152
|
Returns:
|
|
129
|
-
A list of
|
|
130
|
-
Stores unique configs by server_id internally.
|
|
153
|
+
A list of the successfully added McpServerConfig objects.
|
|
131
154
|
"""
|
|
132
155
|
loaded_mcp_configs: List[BaseMcpConfig] = []
|
|
133
156
|
|
|
@@ -139,119 +162,75 @@ class McpConfigService(metaclass=SingletonMeta):
|
|
|
139
162
|
with open(source, 'r', encoding='utf-8') as f:
|
|
140
163
|
json_data = json.load(f)
|
|
141
164
|
logger.info(f"Successfully loaded JSON data from file: {source}")
|
|
142
|
-
# Recursive call with the parsed JSON data
|
|
143
165
|
return self.load_configs(json_data)
|
|
144
166
|
except json.JSONDecodeError as e:
|
|
145
|
-
logger.error(f"Error decoding JSON from MCP configuration file {source}: {e}")
|
|
146
167
|
raise ValueError(f"Invalid JSON in MCP configuration file {source}: {e}") from e
|
|
147
168
|
except Exception as e:
|
|
148
|
-
logger.error(f"Error reading MCP configuration file {source}: {e}")
|
|
149
169
|
raise ValueError(f"Could not read MCP configuration file {source}: {e}") from e
|
|
150
170
|
|
|
151
171
|
elif isinstance(source, list):
|
|
152
|
-
|
|
153
|
-
for i, config_item_dict in enumerate(source): # Renamed from config_dict to avoid confusion
|
|
172
|
+
for i, config_item_dict in enumerate(source):
|
|
154
173
|
if not isinstance(config_item_dict, dict):
|
|
155
174
|
raise ValueError(f"Item at index {i} in source list is not a dictionary.")
|
|
156
175
|
|
|
157
|
-
|
|
158
|
-
if not
|
|
176
|
+
server_id = config_item_dict.get('server_id')
|
|
177
|
+
if not server_id:
|
|
159
178
|
raise ValueError(f"Item at index {i} in source list is missing 'server_id' field.")
|
|
160
179
|
|
|
161
|
-
transport_type_str = config_item_dict.get('transport_type')
|
|
162
|
-
if not transport_type_str:
|
|
163
|
-
raise ValueError(f"Item at index {i} (server '{current_server_id}') in source list is missing 'transport_type' field.")
|
|
164
|
-
|
|
165
180
|
try:
|
|
166
|
-
|
|
167
|
-
#
|
|
168
|
-
config_obj =
|
|
169
|
-
|
|
170
|
-
if config_obj.server_id in self._configs:
|
|
171
|
-
logger.warning(f"Duplicate MCP config server_id '{config_obj.server_id}' found in list. Overwriting previous entry.")
|
|
172
|
-
self._configs[config_obj.server_id] = config_obj
|
|
181
|
+
# A list item is a single config, but doesn't have the server_id as the key,
|
|
182
|
+
# so we wrap it to use the parser.
|
|
183
|
+
config_obj = McpConfigService.parse_mcp_config_dict({server_id: config_item_dict})
|
|
184
|
+
self.add_config(config_obj)
|
|
173
185
|
loaded_mcp_configs.append(config_obj)
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
raise ValueError(f"Invalid MCP configuration data (list item at index {i}, server '{current_server_id}'): {e}") from e
|
|
186
|
+
except ValueError as e:
|
|
187
|
+
logger.error(f"Invalid MCP configuration for list item at index {i}: {e}")
|
|
188
|
+
raise
|
|
178
189
|
|
|
179
190
|
elif isinstance(source, dict):
|
|
180
|
-
logger.info(
|
|
181
|
-
for
|
|
182
|
-
if not isinstance(
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
transport_type_str = config_value_dict.get('transport_type')
|
|
186
|
-
if not transport_type_str:
|
|
187
|
-
raise ValueError(f"Config data for server '{server_config_key_id}' is missing 'transport_type' field.")
|
|
191
|
+
logger.info("Loading MCP server configurations from a dictionary of configs (keyed by server_id).")
|
|
192
|
+
for server_id, config_data in source.items():
|
|
193
|
+
if not isinstance(config_data, dict):
|
|
194
|
+
raise ValueError(f"Configuration for server_id '{server_id}' must be a dictionary.")
|
|
188
195
|
|
|
189
196
|
try:
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
config_obj = self._create_specific_config(server_config_key_id, transport_type_enum, config_value_dict)
|
|
193
|
-
|
|
194
|
-
if config_obj.server_id in self._configs:
|
|
195
|
-
logger.warning(f"Duplicate MCP config server_id '{config_obj.server_id}' found in dictionary. Overwriting previous entry.")
|
|
196
|
-
self._configs[config_obj.server_id] = config_obj
|
|
197
|
+
config_obj = McpConfigService.parse_mcp_config_dict({server_id: config_data})
|
|
198
|
+
self.add_config(config_obj)
|
|
197
199
|
loaded_mcp_configs.append(config_obj)
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
raise ValueError(f"Invalid MCP configuration data (dict entry for server_id '{server_config_key_id}'): {e}") from e
|
|
200
|
+
except ValueError as e:
|
|
201
|
+
logger.error(f"Invalid MCP configuration for server_id '{server_id}': {e}")
|
|
202
|
+
raise
|
|
202
203
|
else:
|
|
203
|
-
raise TypeError(f"Unsupported source type for
|
|
204
|
-
"Expected file path
|
|
204
|
+
raise TypeError(f"Unsupported source type for load_configs: {type(source)}. "
|
|
205
|
+
"Expected file path, list of dicts, or dict of dicts.")
|
|
205
206
|
|
|
206
207
|
logger.info(f"McpConfigService load_configs completed. {len(loaded_mcp_configs)} new configurations processed. "
|
|
207
208
|
f"Total unique configs stored: {len(self._configs)}.")
|
|
208
209
|
return loaded_mcp_configs
|
|
209
210
|
|
|
210
|
-
def
|
|
211
|
-
"""
|
|
212
|
-
|
|
213
|
-
The configuration object must be an instance of a BaseMcpConfig subclass
|
|
214
|
-
(e.g., StdioMcpServerConfig, SseMcpServerConfig).
|
|
215
|
-
If a configuration with the same server_id already exists, it will be overwritten.
|
|
216
|
-
|
|
217
|
-
Args:
|
|
218
|
-
config_object: A BaseMcpConfig subclass instance (e.g., StdioMcpServerConfig).
|
|
211
|
+
def get_config(self, server_id: str) -> Optional[BaseMcpConfig]:
|
|
212
|
+
"""Retrieves an MCP server configuration by its unique server ID."""
|
|
213
|
+
return self._configs.get(server_id)
|
|
219
214
|
|
|
220
|
-
|
|
221
|
-
|
|
215
|
+
def get_all_configs(self) -> List[BaseMcpConfig]:
|
|
216
|
+
return list(self._configs.values())
|
|
222
217
|
|
|
223
|
-
|
|
224
|
-
TypeError: If config_object is not a BaseMcpConfig subclass instance.
|
|
218
|
+
def remove_config(self, server_id: str) -> bool:
|
|
225
219
|
"""
|
|
226
|
-
|
|
227
|
-
raise TypeError(f"Unsupported input type for add_config: {type(config_object)}. "
|
|
228
|
-
"Expected a BaseMcpConfig subclass object (e.g., StdioMcpServerConfig).")
|
|
220
|
+
Removes an MCP server configuration by its unique server ID.
|
|
229
221
|
|
|
230
|
-
logger.debug(f"Attempting to add provided {type(config_object).__name__} object with server_id: '{config_object.server_id}'.")
|
|
231
|
-
|
|
232
|
-
if config_object.server_id in self._configs:
|
|
233
|
-
logger.warning(f"Overwriting existing MCP config with server_id '{config_object.server_id}'.")
|
|
234
|
-
|
|
235
|
-
self._configs[config_object.server_id] = config_object
|
|
236
|
-
logger.info(f"Successfully added/updated {type(config_object).__name__} for server_id '{config_object.server_id}'. "
|
|
237
|
-
f"Total unique configs stored: {len(self._configs)}.")
|
|
238
|
-
return config_object
|
|
239
|
-
|
|
240
|
-
def get_config(self, server_id: str) -> Optional[BaseMcpConfig]:
|
|
241
|
-
"""
|
|
242
|
-
Retrieves an MCP server configuration by its unique server ID.
|
|
243
222
|
Args:
|
|
244
|
-
server_id: The unique ID of the MCP server configuration.
|
|
223
|
+
server_id: The unique ID of the MCP server configuration to remove.
|
|
224
|
+
|
|
245
225
|
Returns:
|
|
246
|
-
|
|
226
|
+
True if a configuration was found and removed, False otherwise.
|
|
247
227
|
"""
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
logger.
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
return list(self._configs.values())
|
|
228
|
+
if server_id in self._configs:
|
|
229
|
+
del self._configs[server_id]
|
|
230
|
+
logger.info(f"Successfully removed MCP config for server_id '{server_id}'.")
|
|
231
|
+
return True
|
|
232
|
+
logger.warning(f"Attempted to remove MCP config for server_id '{server_id}', but it was not found.")
|
|
233
|
+
return False
|
|
255
234
|
|
|
256
235
|
def clear_configs(self) -> None:
|
|
257
236
|
self._configs.clear()
|