gopher-mcp-python 0.1.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.
- gopher_mcp_python/__init__.py +52 -0
- gopher_mcp_python/agent.py +267 -0
- gopher_mcp_python/config.py +172 -0
- gopher_mcp_python/errors.py +38 -0
- gopher_mcp_python/ffi/__init__.py +7 -0
- gopher_mcp_python/ffi/library.py +365 -0
- gopher_mcp_python/result.py +192 -0
- gopher_mcp_python/server_config.py +47 -0
- gopher_mcp_python-0.1.1.dist-info/METADATA +269 -0
- gopher_mcp_python-0.1.1.dist-info/RECORD +13 -0
- gopher_mcp_python-0.1.1.dist-info/WHEEL +5 -0
- gopher_mcp_python-0.1.1.dist-info/licenses/LICENSE +201 -0
- gopher_mcp_python-0.1.1.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Gopher Orch Python SDK - AI Agent orchestration framework with native performance.
|
|
3
|
+
|
|
4
|
+
This module provides Python bindings to the gopher-mcp-python native library through ctypes FFI.
|
|
5
|
+
|
|
6
|
+
Example:
|
|
7
|
+
>>> from gopher_mcp_python import GopherAgent, GopherAgentConfig
|
|
8
|
+
>>>
|
|
9
|
+
>>> # Create an agent with API key
|
|
10
|
+
>>> config = (GopherAgentConfig.builder()
|
|
11
|
+
... .provider("AnthropicProvider")
|
|
12
|
+
... .model("claude-3-haiku-20240307")
|
|
13
|
+
... .api_key("your-api-key")
|
|
14
|
+
... .build())
|
|
15
|
+
>>> agent = GopherAgent.create(config)
|
|
16
|
+
>>>
|
|
17
|
+
>>> # Run a query
|
|
18
|
+
>>> answer = agent.run("What time is it in Tokyo?")
|
|
19
|
+
>>> print(answer)
|
|
20
|
+
>>>
|
|
21
|
+
>>> # Cleanup
|
|
22
|
+
>>> agent.dispose()
|
|
23
|
+
"""
|
|
24
|
+
|
|
25
|
+
from gopher_mcp_python.agent import GopherAgent
|
|
26
|
+
from gopher_mcp_python.config import GopherAgentConfig, GopherAgentConfigBuilder
|
|
27
|
+
from gopher_mcp_python.result import AgentResult, AgentResultStatus, AgentResultBuilder
|
|
28
|
+
from gopher_mcp_python.errors import AgentError, ApiKeyError, ConnectionError, TimeoutError
|
|
29
|
+
from gopher_mcp_python.server_config import ServerConfig
|
|
30
|
+
from gopher_mcp_python.ffi import GopherOrchLibrary
|
|
31
|
+
|
|
32
|
+
__version__ = "0.1.1"
|
|
33
|
+
|
|
34
|
+
__all__ = [
|
|
35
|
+
# Main classes
|
|
36
|
+
"GopherAgent",
|
|
37
|
+
"GopherAgentConfig",
|
|
38
|
+
"GopherAgentConfigBuilder",
|
|
39
|
+
"AgentResult",
|
|
40
|
+
"AgentResultStatus",
|
|
41
|
+
"AgentResultBuilder",
|
|
42
|
+
"ServerConfig",
|
|
43
|
+
# Errors
|
|
44
|
+
"AgentError",
|
|
45
|
+
"ApiKeyError",
|
|
46
|
+
"ConnectionError",
|
|
47
|
+
"TimeoutError",
|
|
48
|
+
# FFI
|
|
49
|
+
"GopherOrchLibrary",
|
|
50
|
+
# Version
|
|
51
|
+
"__version__",
|
|
52
|
+
]
|
|
@@ -0,0 +1,267 @@
|
|
|
1
|
+
"""
|
|
2
|
+
GopherAgent - Main entry point for the gopher-mcp-python Python SDK.
|
|
3
|
+
|
|
4
|
+
Provides a clean, Pythonic interface to the gopher-mcp-python agent functionality.
|
|
5
|
+
|
|
6
|
+
Example:
|
|
7
|
+
# Create an agent with API key
|
|
8
|
+
config = (GopherAgentConfig.builder()
|
|
9
|
+
.provider("AnthropicProvider")
|
|
10
|
+
.model("claude-3-haiku-20240307")
|
|
11
|
+
.api_key("your-api-key")
|
|
12
|
+
.build())
|
|
13
|
+
|
|
14
|
+
agent = GopherAgent.create(config)
|
|
15
|
+
|
|
16
|
+
# Run a query
|
|
17
|
+
answer = agent.run("What time is it in Tokyo?")
|
|
18
|
+
print(answer)
|
|
19
|
+
|
|
20
|
+
# Cleanup
|
|
21
|
+
agent.dispose()
|
|
22
|
+
|
|
23
|
+
Example with context manager:
|
|
24
|
+
with GopherAgent.create(config) as agent:
|
|
25
|
+
answer = agent.run("What time is it in Tokyo?")
|
|
26
|
+
print(answer)
|
|
27
|
+
"""
|
|
28
|
+
|
|
29
|
+
import atexit
|
|
30
|
+
from typing import Optional
|
|
31
|
+
|
|
32
|
+
from gopher_mcp_python.config import GopherAgentConfig
|
|
33
|
+
from gopher_mcp_python.result import AgentResult, AgentResultStatus
|
|
34
|
+
from gopher_mcp_python.errors import AgentError, TimeoutError
|
|
35
|
+
from gopher_mcp_python.ffi import GopherOrchLibrary, GopherOrchHandle
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
_initialized = False
|
|
39
|
+
_cleanup_handler_registered = False
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
class GopherAgent:
|
|
43
|
+
"""
|
|
44
|
+
Main agent class for interacting with the gopher-mcp-python native library.
|
|
45
|
+
"""
|
|
46
|
+
|
|
47
|
+
def __init__(self, handle: GopherOrchHandle) -> None:
|
|
48
|
+
"""
|
|
49
|
+
Initialize a GopherAgent with a native handle.
|
|
50
|
+
|
|
51
|
+
Note: Use create() factory method instead of direct instantiation.
|
|
52
|
+
"""
|
|
53
|
+
self._handle = handle
|
|
54
|
+
self._disposed = False
|
|
55
|
+
|
|
56
|
+
def __enter__(self) -> "GopherAgent":
|
|
57
|
+
"""Context manager entry."""
|
|
58
|
+
return self
|
|
59
|
+
|
|
60
|
+
def __exit__(self, exc_type, exc_val, exc_tb) -> None:
|
|
61
|
+
"""Context manager exit with automatic cleanup."""
|
|
62
|
+
self.dispose()
|
|
63
|
+
|
|
64
|
+
@staticmethod
|
|
65
|
+
def init() -> None:
|
|
66
|
+
"""
|
|
67
|
+
Initialize the gopher-mcp-python library.
|
|
68
|
+
|
|
69
|
+
Must be called before creating any agents. Called automatically by
|
|
70
|
+
create() if not already initialized.
|
|
71
|
+
|
|
72
|
+
Raises:
|
|
73
|
+
AgentError: if initialization fails
|
|
74
|
+
"""
|
|
75
|
+
global _initialized
|
|
76
|
+
if _initialized:
|
|
77
|
+
return
|
|
78
|
+
|
|
79
|
+
lib = GopherOrchLibrary.get_instance()
|
|
80
|
+
if lib is None:
|
|
81
|
+
raise AgentError("Failed to load gopher-mcp-python native library")
|
|
82
|
+
|
|
83
|
+
_initialized = True
|
|
84
|
+
_setup_cleanup_handler()
|
|
85
|
+
|
|
86
|
+
@staticmethod
|
|
87
|
+
def shutdown() -> None:
|
|
88
|
+
"""
|
|
89
|
+
Shutdown the gopher-mcp-python library.
|
|
90
|
+
|
|
91
|
+
Called automatically on process exit, but can be called manually.
|
|
92
|
+
"""
|
|
93
|
+
global _initialized
|
|
94
|
+
_initialized = False
|
|
95
|
+
|
|
96
|
+
@staticmethod
|
|
97
|
+
def is_initialized() -> bool:
|
|
98
|
+
"""Check if the library is initialized."""
|
|
99
|
+
return _initialized
|
|
100
|
+
|
|
101
|
+
@staticmethod
|
|
102
|
+
def create(config: GopherAgentConfig) -> "GopherAgent":
|
|
103
|
+
"""
|
|
104
|
+
Create a new GopherAgent instance.
|
|
105
|
+
|
|
106
|
+
Args:
|
|
107
|
+
config: Agent configuration
|
|
108
|
+
|
|
109
|
+
Returns:
|
|
110
|
+
GopherAgent instance
|
|
111
|
+
|
|
112
|
+
Raises:
|
|
113
|
+
AgentError: if agent creation fails
|
|
114
|
+
"""
|
|
115
|
+
if not _initialized:
|
|
116
|
+
GopherAgent.init()
|
|
117
|
+
|
|
118
|
+
lib = GopherOrchLibrary.get_instance()
|
|
119
|
+
if lib is None:
|
|
120
|
+
raise AgentError("Native library not available")
|
|
121
|
+
|
|
122
|
+
handle: Optional[GopherOrchHandle] = None
|
|
123
|
+
try:
|
|
124
|
+
if config.has_api_key():
|
|
125
|
+
handle = lib.agent_create_by_api_key(
|
|
126
|
+
config.provider, config.model, config.api_key
|
|
127
|
+
)
|
|
128
|
+
else:
|
|
129
|
+
handle = lib.agent_create_by_json(
|
|
130
|
+
config.provider, config.model, config.server_config
|
|
131
|
+
)
|
|
132
|
+
except Exception as e:
|
|
133
|
+
raise AgentError(f"Failed to create agent: {e}")
|
|
134
|
+
|
|
135
|
+
if handle is None:
|
|
136
|
+
error = lib.get_last_error_message()
|
|
137
|
+
lib.clear_error()
|
|
138
|
+
raise AgentError(error or "Failed to create agent")
|
|
139
|
+
|
|
140
|
+
return GopherAgent(handle)
|
|
141
|
+
|
|
142
|
+
@staticmethod
|
|
143
|
+
def create_with_api_key(provider: str, model: str, api_key: str) -> "GopherAgent":
|
|
144
|
+
"""
|
|
145
|
+
Create a new GopherAgent with API key.
|
|
146
|
+
|
|
147
|
+
Args:
|
|
148
|
+
provider: Provider name (e.g., "AnthropicProvider")
|
|
149
|
+
model: Model name (e.g., "claude-3-haiku-20240307")
|
|
150
|
+
api_key: API key for fetching remote server config
|
|
151
|
+
|
|
152
|
+
Returns:
|
|
153
|
+
GopherAgent instance
|
|
154
|
+
"""
|
|
155
|
+
return GopherAgent.create(
|
|
156
|
+
GopherAgentConfig.builder()
|
|
157
|
+
.provider(provider)
|
|
158
|
+
.model(model)
|
|
159
|
+
.api_key(api_key)
|
|
160
|
+
.build()
|
|
161
|
+
)
|
|
162
|
+
|
|
163
|
+
@staticmethod
|
|
164
|
+
def create_with_server_config(
|
|
165
|
+
provider: str, model: str, server_config: str
|
|
166
|
+
) -> "GopherAgent":
|
|
167
|
+
"""
|
|
168
|
+
Create a new GopherAgent with JSON server config.
|
|
169
|
+
|
|
170
|
+
Args:
|
|
171
|
+
provider: Provider name (e.g., "AnthropicProvider")
|
|
172
|
+
model: Model name (e.g., "claude-3-haiku-20240307")
|
|
173
|
+
server_config: JSON server configuration
|
|
174
|
+
|
|
175
|
+
Returns:
|
|
176
|
+
GopherAgent instance
|
|
177
|
+
"""
|
|
178
|
+
return GopherAgent.create(
|
|
179
|
+
GopherAgentConfig.builder()
|
|
180
|
+
.provider(provider)
|
|
181
|
+
.model(model)
|
|
182
|
+
.server_config(server_config)
|
|
183
|
+
.build()
|
|
184
|
+
)
|
|
185
|
+
|
|
186
|
+
def run(self, query: str, timeout_ms: int = 60000) -> str:
|
|
187
|
+
"""
|
|
188
|
+
Run a query against the agent.
|
|
189
|
+
|
|
190
|
+
Args:
|
|
191
|
+
query: The user query to process
|
|
192
|
+
timeout_ms: Timeout in milliseconds (default: 60000)
|
|
193
|
+
|
|
194
|
+
Returns:
|
|
195
|
+
The agent's response
|
|
196
|
+
|
|
197
|
+
Raises:
|
|
198
|
+
AgentError: if the query fails
|
|
199
|
+
"""
|
|
200
|
+
self._ensure_not_disposed()
|
|
201
|
+
|
|
202
|
+
lib = GopherOrchLibrary.get_instance()
|
|
203
|
+
if lib is None:
|
|
204
|
+
raise AgentError("Native library not available")
|
|
205
|
+
|
|
206
|
+
try:
|
|
207
|
+
response = lib.agent_run(self._handle, query, timeout_ms)
|
|
208
|
+
if response is None:
|
|
209
|
+
return f'No response for query: "{query}"'
|
|
210
|
+
return response
|
|
211
|
+
except Exception as e:
|
|
212
|
+
raise AgentError(f"Query execution failed: {e}")
|
|
213
|
+
|
|
214
|
+
def run_detailed(self, query: str, timeout_ms: int = 60000) -> AgentResult:
|
|
215
|
+
"""
|
|
216
|
+
Run a query with detailed result information.
|
|
217
|
+
|
|
218
|
+
Args:
|
|
219
|
+
query: The user query to process
|
|
220
|
+
timeout_ms: Timeout in milliseconds (default: 60000)
|
|
221
|
+
|
|
222
|
+
Returns:
|
|
223
|
+
AgentResult with response and metadata
|
|
224
|
+
"""
|
|
225
|
+
try:
|
|
226
|
+
response = self.run(query, timeout_ms)
|
|
227
|
+
return (
|
|
228
|
+
AgentResult.builder()
|
|
229
|
+
.response(response)
|
|
230
|
+
.status(AgentResultStatus.SUCCESS)
|
|
231
|
+
.iteration_count(1)
|
|
232
|
+
.tokens_used(0)
|
|
233
|
+
.build()
|
|
234
|
+
)
|
|
235
|
+
except TimeoutError as e:
|
|
236
|
+
return AgentResult.timeout(str(e))
|
|
237
|
+
except Exception as e:
|
|
238
|
+
return AgentResult.error(str(e))
|
|
239
|
+
|
|
240
|
+
def dispose(self) -> None:
|
|
241
|
+
"""Dispose of the agent and free resources."""
|
|
242
|
+
if self._disposed:
|
|
243
|
+
return
|
|
244
|
+
|
|
245
|
+
self._disposed = True
|
|
246
|
+
lib = GopherOrchLibrary.get_instance()
|
|
247
|
+
if lib is not None and self._handle is not None:
|
|
248
|
+
lib.agent_release(self._handle)
|
|
249
|
+
|
|
250
|
+
def is_disposed(self) -> bool:
|
|
251
|
+
"""Check if agent is disposed."""
|
|
252
|
+
return self._disposed
|
|
253
|
+
|
|
254
|
+
def _ensure_not_disposed(self) -> None:
|
|
255
|
+
"""Ensure agent has not been disposed."""
|
|
256
|
+
if self._disposed:
|
|
257
|
+
raise AgentError("Agent has been disposed")
|
|
258
|
+
|
|
259
|
+
|
|
260
|
+
def _setup_cleanup_handler() -> None:
|
|
261
|
+
"""Register cleanup handler for process exit."""
|
|
262
|
+
global _cleanup_handler_registered
|
|
263
|
+
if _cleanup_handler_registered:
|
|
264
|
+
return
|
|
265
|
+
|
|
266
|
+
_cleanup_handler_registered = True
|
|
267
|
+
atexit.register(GopherAgent.shutdown)
|
|
@@ -0,0 +1,172 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Configuration classes for the Gopher Security MCP SDK.
|
|
3
|
+
|
|
4
|
+
Provides a builder pattern for creating agent configurations with validation.
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
from typing import Optional
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
class GopherAgentConfig:
|
|
11
|
+
"""
|
|
12
|
+
Immutable configuration for GopherAgent.
|
|
13
|
+
|
|
14
|
+
Use the builder() method to create configurations.
|
|
15
|
+
|
|
16
|
+
Example:
|
|
17
|
+
>>> config = (GopherAgentConfig.builder()
|
|
18
|
+
... .provider("AnthropicProvider")
|
|
19
|
+
... .model("claude-3-haiku-20240307")
|
|
20
|
+
... .api_key("your-api-key")
|
|
21
|
+
... .build())
|
|
22
|
+
"""
|
|
23
|
+
|
|
24
|
+
def __init__(
|
|
25
|
+
self,
|
|
26
|
+
provider: str,
|
|
27
|
+
model: str,
|
|
28
|
+
api_key: Optional[str] = None,
|
|
29
|
+
server_config: Optional[str] = None,
|
|
30
|
+
) -> None:
|
|
31
|
+
"""
|
|
32
|
+
Initialize a GopherAgentConfig.
|
|
33
|
+
|
|
34
|
+
Args:
|
|
35
|
+
provider: The LLM provider name (e.g., "AnthropicProvider")
|
|
36
|
+
model: The model name (e.g., "claude-3-haiku-20240307")
|
|
37
|
+
api_key: API key for fetching remote server config
|
|
38
|
+
server_config: JSON server configuration string
|
|
39
|
+
"""
|
|
40
|
+
self._provider = provider
|
|
41
|
+
self._model = model
|
|
42
|
+
self._api_key = api_key
|
|
43
|
+
self._server_config = server_config
|
|
44
|
+
|
|
45
|
+
@property
|
|
46
|
+
def provider(self) -> str:
|
|
47
|
+
"""Get the provider name."""
|
|
48
|
+
return self._provider
|
|
49
|
+
|
|
50
|
+
@property
|
|
51
|
+
def model(self) -> str:
|
|
52
|
+
"""Get the model name."""
|
|
53
|
+
return self._model
|
|
54
|
+
|
|
55
|
+
@property
|
|
56
|
+
def api_key(self) -> Optional[str]:
|
|
57
|
+
"""Get the API key."""
|
|
58
|
+
return self._api_key
|
|
59
|
+
|
|
60
|
+
@property
|
|
61
|
+
def server_config(self) -> Optional[str]:
|
|
62
|
+
"""Get the server configuration JSON."""
|
|
63
|
+
return self._server_config
|
|
64
|
+
|
|
65
|
+
def has_api_key(self) -> bool:
|
|
66
|
+
"""Check if configuration uses API key."""
|
|
67
|
+
return self._api_key is not None
|
|
68
|
+
|
|
69
|
+
def has_server_config(self) -> bool:
|
|
70
|
+
"""Check if configuration uses server config."""
|
|
71
|
+
return self._server_config is not None
|
|
72
|
+
|
|
73
|
+
@staticmethod
|
|
74
|
+
def builder() -> "GopherAgentConfigBuilder":
|
|
75
|
+
"""Create a new configuration builder."""
|
|
76
|
+
return GopherAgentConfigBuilder()
|
|
77
|
+
|
|
78
|
+
|
|
79
|
+
class GopherAgentConfigBuilder:
|
|
80
|
+
"""
|
|
81
|
+
Builder for GopherAgentConfig.
|
|
82
|
+
|
|
83
|
+
Provides a fluent interface for building configurations with validation.
|
|
84
|
+
"""
|
|
85
|
+
|
|
86
|
+
def __init__(self) -> None:
|
|
87
|
+
self._provider: Optional[str] = None
|
|
88
|
+
self._model: Optional[str] = None
|
|
89
|
+
self._api_key: Optional[str] = None
|
|
90
|
+
self._server_config: Optional[str] = None
|
|
91
|
+
|
|
92
|
+
def provider(self, provider: str) -> "GopherAgentConfigBuilder":
|
|
93
|
+
"""
|
|
94
|
+
Set the LLM provider.
|
|
95
|
+
|
|
96
|
+
Args:
|
|
97
|
+
provider: The provider name (e.g., "AnthropicProvider", "OpenAIProvider")
|
|
98
|
+
|
|
99
|
+
Returns:
|
|
100
|
+
self for chaining
|
|
101
|
+
"""
|
|
102
|
+
self._provider = provider
|
|
103
|
+
return self
|
|
104
|
+
|
|
105
|
+
def model(self, model: str) -> "GopherAgentConfigBuilder":
|
|
106
|
+
"""
|
|
107
|
+
Set the model name.
|
|
108
|
+
|
|
109
|
+
Args:
|
|
110
|
+
model: The model name (e.g., "claude-3-haiku-20240307")
|
|
111
|
+
|
|
112
|
+
Returns:
|
|
113
|
+
self for chaining
|
|
114
|
+
"""
|
|
115
|
+
self._model = model
|
|
116
|
+
return self
|
|
117
|
+
|
|
118
|
+
def api_key(self, api_key: str) -> "GopherAgentConfigBuilder":
|
|
119
|
+
"""
|
|
120
|
+
Set the API key for fetching remote server config.
|
|
121
|
+
|
|
122
|
+
Mutually exclusive with server_config().
|
|
123
|
+
|
|
124
|
+
Args:
|
|
125
|
+
api_key: The API key
|
|
126
|
+
|
|
127
|
+
Returns:
|
|
128
|
+
self for chaining
|
|
129
|
+
"""
|
|
130
|
+
self._api_key = api_key
|
|
131
|
+
return self
|
|
132
|
+
|
|
133
|
+
def server_config(self, server_config: str) -> "GopherAgentConfigBuilder":
|
|
134
|
+
"""
|
|
135
|
+
Set the JSON server configuration.
|
|
136
|
+
|
|
137
|
+
Mutually exclusive with api_key().
|
|
138
|
+
|
|
139
|
+
Args:
|
|
140
|
+
server_config: JSON string containing server configuration
|
|
141
|
+
|
|
142
|
+
Returns:
|
|
143
|
+
self for chaining
|
|
144
|
+
"""
|
|
145
|
+
self._server_config = server_config
|
|
146
|
+
return self
|
|
147
|
+
|
|
148
|
+
def build(self) -> GopherAgentConfig:
|
|
149
|
+
"""
|
|
150
|
+
Build the configuration.
|
|
151
|
+
|
|
152
|
+
Returns:
|
|
153
|
+
GopherAgentConfig instance
|
|
154
|
+
|
|
155
|
+
Raises:
|
|
156
|
+
ValueError: If required fields are missing or configuration is invalid
|
|
157
|
+
"""
|
|
158
|
+
if not self._provider:
|
|
159
|
+
raise ValueError("Provider is required")
|
|
160
|
+
if not self._model:
|
|
161
|
+
raise ValueError("Model is required")
|
|
162
|
+
if not self._api_key and not self._server_config:
|
|
163
|
+
raise ValueError("Either api_key or server_config is required")
|
|
164
|
+
if self._api_key and self._server_config:
|
|
165
|
+
raise ValueError("Cannot specify both api_key and server_config")
|
|
166
|
+
|
|
167
|
+
return GopherAgentConfig(
|
|
168
|
+
provider=self._provider,
|
|
169
|
+
model=self._model,
|
|
170
|
+
api_key=self._api_key,
|
|
171
|
+
server_config=self._server_config,
|
|
172
|
+
)
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Custom error classes for the Gopher Security MCP SDK.
|
|
3
|
+
|
|
4
|
+
Provides typed exceptions for different error conditions:
|
|
5
|
+
- AgentError: Base class for all agent-related errors
|
|
6
|
+
- ApiKeyError: Invalid or missing API key
|
|
7
|
+
- ConnectionError: Network or connection failures
|
|
8
|
+
- TimeoutError: Operation timed out
|
|
9
|
+
"""
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
class AgentError(Exception):
|
|
13
|
+
"""Base exception for agent-related errors."""
|
|
14
|
+
|
|
15
|
+
def __init__(self, message: str) -> None:
|
|
16
|
+
self.message = message
|
|
17
|
+
super().__init__(message)
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
class ApiKeyError(AgentError):
|
|
21
|
+
"""Exception raised when API key is invalid or missing."""
|
|
22
|
+
|
|
23
|
+
def __init__(self, message: str = "Invalid or missing API key") -> None:
|
|
24
|
+
super().__init__(message)
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
class ConnectionError(AgentError):
|
|
28
|
+
"""Exception raised when connection to server fails."""
|
|
29
|
+
|
|
30
|
+
def __init__(self, message: str = "Connection failed") -> None:
|
|
31
|
+
super().__init__(message)
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
class TimeoutError(AgentError):
|
|
35
|
+
"""Exception raised when operation times out."""
|
|
36
|
+
|
|
37
|
+
def __init__(self, message: str = "Operation timed out") -> None:
|
|
38
|
+
super().__init__(message)
|