xpander-sdk 1.60.8__py3-none-any.whl → 2.0.155__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.
- xpander_sdk/__init__.py +76 -7793
- xpander_sdk/consts/__init__.py +0 -0
- xpander_sdk/consts/api_routes.py +63 -0
- xpander_sdk/core/__init__.py +0 -0
- xpander_sdk/core/module_base.py +164 -0
- xpander_sdk/core/state.py +10 -0
- xpander_sdk/core/xpander_api_client.py +119 -0
- xpander_sdk/exceptions/__init__.py +0 -0
- xpander_sdk/exceptions/module_exception.py +45 -0
- xpander_sdk/models/__init__.py +0 -0
- xpander_sdk/models/activity.py +65 -0
- xpander_sdk/models/configuration.py +92 -0
- xpander_sdk/models/events.py +70 -0
- xpander_sdk/models/frameworks.py +64 -0
- xpander_sdk/models/shared.py +102 -0
- xpander_sdk/models/user.py +21 -0
- xpander_sdk/modules/__init__.py +0 -0
- xpander_sdk/modules/agents/__init__.py +0 -0
- xpander_sdk/modules/agents/agents_module.py +164 -0
- xpander_sdk/modules/agents/models/__init__.py +0 -0
- xpander_sdk/modules/agents/models/agent.py +477 -0
- xpander_sdk/modules/agents/models/agent_list.py +107 -0
- xpander_sdk/modules/agents/models/knowledge_bases.py +33 -0
- xpander_sdk/modules/agents/sub_modules/__init__.py +0 -0
- xpander_sdk/modules/agents/sub_modules/agent.py +953 -0
- xpander_sdk/modules/agents/utils/__init__.py +0 -0
- xpander_sdk/modules/agents/utils/generic.py +2 -0
- xpander_sdk/modules/backend/__init__.py +0 -0
- xpander_sdk/modules/backend/backend_module.py +425 -0
- xpander_sdk/modules/backend/frameworks/__init__.py +0 -0
- xpander_sdk/modules/backend/frameworks/agno.py +627 -0
- xpander_sdk/modules/backend/frameworks/dispatch.py +36 -0
- xpander_sdk/modules/backend/utils/__init__.py +0 -0
- xpander_sdk/modules/backend/utils/mcp_oauth.py +95 -0
- xpander_sdk/modules/events/__init__.py +0 -0
- xpander_sdk/modules/events/decorators/__init__.py +0 -0
- xpander_sdk/modules/events/decorators/on_boot.py +94 -0
- xpander_sdk/modules/events/decorators/on_shutdown.py +94 -0
- xpander_sdk/modules/events/decorators/on_task.py +203 -0
- xpander_sdk/modules/events/events_module.py +629 -0
- xpander_sdk/modules/events/models/__init__.py +0 -0
- xpander_sdk/modules/events/models/deployments.py +25 -0
- xpander_sdk/modules/events/models/events.py +57 -0
- xpander_sdk/modules/events/utils/__init__.py +0 -0
- xpander_sdk/modules/events/utils/generic.py +56 -0
- xpander_sdk/modules/events/utils/git_init.py +32 -0
- xpander_sdk/modules/knowledge_bases/__init__.py +0 -0
- xpander_sdk/modules/knowledge_bases/knowledge_bases_module.py +217 -0
- xpander_sdk/modules/knowledge_bases/models/__init__.py +0 -0
- xpander_sdk/modules/knowledge_bases/models/knowledge_bases.py +11 -0
- xpander_sdk/modules/knowledge_bases/sub_modules/__init__.py +0 -0
- xpander_sdk/modules/knowledge_bases/sub_modules/knowledge_base.py +107 -0
- xpander_sdk/modules/knowledge_bases/sub_modules/knowledge_base_document_item.py +40 -0
- xpander_sdk/modules/knowledge_bases/utils/__init__.py +0 -0
- xpander_sdk/modules/tasks/__init__.py +0 -0
- xpander_sdk/modules/tasks/models/__init__.py +0 -0
- xpander_sdk/modules/tasks/models/task.py +153 -0
- xpander_sdk/modules/tasks/models/tasks_list.py +107 -0
- xpander_sdk/modules/tasks/sub_modules/__init__.py +0 -0
- xpander_sdk/modules/tasks/sub_modules/task.py +887 -0
- xpander_sdk/modules/tasks/tasks_module.py +492 -0
- xpander_sdk/modules/tasks/utils/__init__.py +0 -0
- xpander_sdk/modules/tasks/utils/files.py +114 -0
- xpander_sdk/modules/tools_repository/__init__.py +0 -0
- xpander_sdk/modules/tools_repository/decorators/__init__.py +0 -0
- xpander_sdk/modules/tools_repository/decorators/register_tool.py +108 -0
- xpander_sdk/modules/tools_repository/models/__init__.py +0 -0
- xpander_sdk/modules/tools_repository/models/mcp.py +68 -0
- xpander_sdk/modules/tools_repository/models/tool_invocation_result.py +14 -0
- xpander_sdk/modules/tools_repository/sub_modules/__init__.py +0 -0
- xpander_sdk/modules/tools_repository/sub_modules/tool.py +578 -0
- xpander_sdk/modules/tools_repository/tools_repository_module.py +259 -0
- xpander_sdk/modules/tools_repository/utils/__init__.py +0 -0
- xpander_sdk/modules/tools_repository/utils/generic.py +57 -0
- xpander_sdk/modules/tools_repository/utils/local_tools.py +52 -0
- xpander_sdk/modules/tools_repository/utils/schemas.py +308 -0
- xpander_sdk/utils/__init__.py +0 -0
- xpander_sdk/utils/env.py +44 -0
- xpander_sdk/utils/event_loop.py +67 -0
- xpander_sdk/utils/tools.py +32 -0
- xpander_sdk-2.0.155.dist-info/METADATA +538 -0
- xpander_sdk-2.0.155.dist-info/RECORD +85 -0
- {xpander_sdk-1.60.8.dist-info → xpander_sdk-2.0.155.dist-info}/WHEEL +1 -1
- {xpander_sdk-1.60.8.dist-info → xpander_sdk-2.0.155.dist-info/licenses}/LICENSE +0 -1
- xpander_sdk/_jsii/__init__.py +0 -39
- xpander_sdk/_jsii/xpander-sdk@1.60.8.jsii.tgz +0 -0
- xpander_sdk/py.typed +0 -1
- xpander_sdk-1.60.8.dist-info/METADATA +0 -368
- xpander_sdk-1.60.8.dist-info/RECORD +0 -9
- {xpander_sdk-1.60.8.dist-info → xpander_sdk-2.0.155.dist-info}/top_level.txt +0 -0
|
File without changes
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
"""
|
|
2
|
+
API routes configuration for the xpander.ai SDK.
|
|
3
|
+
|
|
4
|
+
This module defines all API endpoint paths used by the xpander.ai SDK for
|
|
5
|
+
autonomous agent management, task operations, and knowledge base interactions.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
from enum import Enum
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
class APIRoute(str, Enum):
|
|
12
|
+
"""
|
|
13
|
+
Enumeration of API endpoints for xpander.ai services.
|
|
14
|
+
|
|
15
|
+
This class defines the paths for interacting with various APIs, including
|
|
16
|
+
agents, tasks, and knowledge bases, standardizing route management across
|
|
17
|
+
the SDK.
|
|
18
|
+
|
|
19
|
+
Attributes include paths for listing, retrieving, creating, updating,
|
|
20
|
+
and deleting resources.
|
|
21
|
+
|
|
22
|
+
Example:
|
|
23
|
+
>>> route = APIRoute.ListAgent
|
|
24
|
+
>>> print(route) # Outputs: /agents/list
|
|
25
|
+
"""
|
|
26
|
+
|
|
27
|
+
# Agents Endpoints
|
|
28
|
+
ListAgent = "/agents/list"
|
|
29
|
+
GetAgent = "/agents/{agent_id}"
|
|
30
|
+
SyncLocalTools = "/agents/{agent_id}/sync_local_tools"
|
|
31
|
+
GetAgentConnectionString = "/agents/{agent_id}/db"
|
|
32
|
+
InvokeTool = "/agents/{agent_id}/operations/{tool_id}"
|
|
33
|
+
|
|
34
|
+
# Tasks Endpoints
|
|
35
|
+
ListTasks = "/agent-execution/executions/history/{agent_id}"
|
|
36
|
+
ListUserTasks = "/agent-execution/executions/history/user/{user_id}"
|
|
37
|
+
GetTask = "/agent-execution/{task_id}/status"
|
|
38
|
+
GetTaskActivityLog = "/activity/{agent_id}/{task_id}"
|
|
39
|
+
TaskCrud = "/agent-execution/{agent_or_task_id}"
|
|
40
|
+
UpdateTask = "/agent-execution/{task_id}/update"
|
|
41
|
+
ReportExternalTask = "/agent-execution/{agent_id}/report_task"
|
|
42
|
+
ReportExecutionMetrics = "/agents-metrics/{agent_id}/execution"
|
|
43
|
+
PushExecutionEventToQueue = "/agent-execution/{task_id}/events/push"
|
|
44
|
+
|
|
45
|
+
# Knowledge Bases Endpoints
|
|
46
|
+
ListKnowledgeBases = "/knowledge_bases"
|
|
47
|
+
CreateKnowledgeBase = "/knowledge_bases/create"
|
|
48
|
+
DeleteKnowledgeBase = "/knowledge_bases/{knowledge_base_id}/erase"
|
|
49
|
+
ListKnowledgeBaseDocuments = "/knowledge_bases/{knowledge_base_id}/list"
|
|
50
|
+
KnowledgeBaseDocumentsCrud = "/knowledge_bases/{knowledge_base_id}"
|
|
51
|
+
GetKnowledgeBaseDetails = "/knowledge_bases/{knowledge_base_id}/details"
|
|
52
|
+
|
|
53
|
+
# MCP Auth
|
|
54
|
+
GetUserMCPAuthToken = "/mcp_auth/{agent_id}/{user_id}/get_token"
|
|
55
|
+
|
|
56
|
+
# Tools
|
|
57
|
+
GetOrInvokeToolById = "/tools/{tool_id}"
|
|
58
|
+
|
|
59
|
+
def __str__(self) -> str:
|
|
60
|
+
return str(self.value)
|
|
61
|
+
|
|
62
|
+
def __repr__(self) -> str:
|
|
63
|
+
return str(self.value)
|
|
File without changes
|
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Base class for all xpander.ai SDK modules.
|
|
3
|
+
|
|
4
|
+
This module provides the abstract base class that all SDK modules inherit from,
|
|
5
|
+
establishing common patterns for resource management and API operations.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
from abc import ABC
|
|
9
|
+
from typing import Optional, Any, Dict, Type
|
|
10
|
+
from xpander_sdk.models.configuration import Configuration
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
class ModuleBase(ABC):
|
|
14
|
+
"""
|
|
15
|
+
Abstract base class for all xpander.ai SDK modules.
|
|
16
|
+
|
|
17
|
+
This class implements a conditional singleton pattern:
|
|
18
|
+
- If no configuration is passed, it returns a shared singleton per subclass.
|
|
19
|
+
- If a configuration is passed, a new instance is created and not shared.
|
|
20
|
+
|
|
21
|
+
Attributes:
|
|
22
|
+
configuration (Configuration): SDK configuration including API credentials
|
|
23
|
+
and endpoint information.
|
|
24
|
+
|
|
25
|
+
Abstract Methods:
|
|
26
|
+
list: List all resources of this module type.
|
|
27
|
+
get: Retrieve a single resource by ID.
|
|
28
|
+
|
|
29
|
+
Optional Methods (can be overridden by subclasses):
|
|
30
|
+
create: Create a new resource.
|
|
31
|
+
update: Update an existing resource.
|
|
32
|
+
delete: Delete a resource.
|
|
33
|
+
"""
|
|
34
|
+
|
|
35
|
+
_shared_instances: Dict[Type['ModuleBase'], 'ModuleBase'] = {}
|
|
36
|
+
|
|
37
|
+
def __new__(cls, configuration: Optional[Configuration] = None):
|
|
38
|
+
"""
|
|
39
|
+
Create or return an existing module singleton instance.
|
|
40
|
+
|
|
41
|
+
Args:
|
|
42
|
+
configuration (Optional[Configuration]): If provided, a new independent
|
|
43
|
+
instance is created. Otherwise, returns a singleton per class.
|
|
44
|
+
|
|
45
|
+
Returns:
|
|
46
|
+
ModuleBase: The module instance.
|
|
47
|
+
"""
|
|
48
|
+
if configuration is not None:
|
|
49
|
+
instance = super().__new__(cls)
|
|
50
|
+
instance._is_custom_instance = True
|
|
51
|
+
return instance
|
|
52
|
+
|
|
53
|
+
if cls not in cls._shared_instances:
|
|
54
|
+
instance = super().__new__(cls)
|
|
55
|
+
instance._is_custom_instance = False
|
|
56
|
+
cls._shared_instances[cls] = instance
|
|
57
|
+
|
|
58
|
+
return cls._shared_instances[cls]
|
|
59
|
+
|
|
60
|
+
def __init__(self, configuration: Optional[Configuration] = None):
|
|
61
|
+
"""
|
|
62
|
+
Initialize the module with configuration.
|
|
63
|
+
|
|
64
|
+
This method is called only once per instance to prevent reinitialization.
|
|
65
|
+
|
|
66
|
+
Args:
|
|
67
|
+
configuration (Optional[Configuration]): SDK configuration. If None,
|
|
68
|
+
will create a default Configuration instance from environment variables.
|
|
69
|
+
"""
|
|
70
|
+
if hasattr(self, '_initialized') and self._initialized:
|
|
71
|
+
return
|
|
72
|
+
|
|
73
|
+
self.configuration = configuration or Configuration()
|
|
74
|
+
self._initialized = True
|
|
75
|
+
|
|
76
|
+
async def list(self, **kwargs) -> Any:
|
|
77
|
+
"""
|
|
78
|
+
List all resources of this module type.
|
|
79
|
+
|
|
80
|
+
This is an abstract method that must be implemented by concrete module classes.
|
|
81
|
+
|
|
82
|
+
Args:
|
|
83
|
+
**kwargs: Additional parameters for filtering, pagination, etc.
|
|
84
|
+
|
|
85
|
+
Returns:
|
|
86
|
+
Any: List of resources or paginated response.
|
|
87
|
+
|
|
88
|
+
Raises:
|
|
89
|
+
NotImplementedError: Always, unless overridden.
|
|
90
|
+
"""
|
|
91
|
+
raise NotImplementedError
|
|
92
|
+
|
|
93
|
+
async def get(self, resource_id: str, **kwargs) -> Any:
|
|
94
|
+
"""
|
|
95
|
+
Retrieve a single resource by its unique identifier.
|
|
96
|
+
|
|
97
|
+
This is an abstract method that must be implemented by concrete module classes.
|
|
98
|
+
|
|
99
|
+
Args:
|
|
100
|
+
resource_id (str): Unique identifier of the resource to retrieve.
|
|
101
|
+
**kwargs: Additional retrieval options.
|
|
102
|
+
|
|
103
|
+
Returns:
|
|
104
|
+
Any: The resource data.
|
|
105
|
+
|
|
106
|
+
Raises:
|
|
107
|
+
NotImplementedError: Always, unless overridden.
|
|
108
|
+
"""
|
|
109
|
+
raise NotImplementedError
|
|
110
|
+
|
|
111
|
+
async def create(self, data: dict, **kwargs) -> Any:
|
|
112
|
+
"""
|
|
113
|
+
Create a new resource (optional operation).
|
|
114
|
+
|
|
115
|
+
Can be overridden by modules that support creation.
|
|
116
|
+
|
|
117
|
+
Args:
|
|
118
|
+
data (dict): Resource data.
|
|
119
|
+
**kwargs: Additional creation options.
|
|
120
|
+
|
|
121
|
+
Returns:
|
|
122
|
+
Any: Created resource data.
|
|
123
|
+
|
|
124
|
+
Raises:
|
|
125
|
+
NotImplementedError: If creation is not supported.
|
|
126
|
+
"""
|
|
127
|
+
raise NotImplementedError("This module does not support 'create'")
|
|
128
|
+
|
|
129
|
+
async def update(self, resource_id: str, data: dict, **kwargs) -> Any:
|
|
130
|
+
"""
|
|
131
|
+
Update an existing resource by ID (optional operation).
|
|
132
|
+
|
|
133
|
+
Can be overridden by modules that support updates.
|
|
134
|
+
|
|
135
|
+
Args:
|
|
136
|
+
resource_id (str): Unique ID of resource to update.
|
|
137
|
+
data (dict): Updated data.
|
|
138
|
+
**kwargs: Additional update options.
|
|
139
|
+
|
|
140
|
+
Returns:
|
|
141
|
+
Any: Updated resource data.
|
|
142
|
+
|
|
143
|
+
Raises:
|
|
144
|
+
NotImplementedError: If update is not supported.
|
|
145
|
+
"""
|
|
146
|
+
raise NotImplementedError("This module does not support 'update'")
|
|
147
|
+
|
|
148
|
+
async def delete(self, resource_id: str, **kwargs) -> Any:
|
|
149
|
+
"""
|
|
150
|
+
Delete a resource by ID (optional operation).
|
|
151
|
+
|
|
152
|
+
Can be overridden by modules that support deletion.
|
|
153
|
+
|
|
154
|
+
Args:
|
|
155
|
+
resource_id (str): Unique ID of resource to delete.
|
|
156
|
+
**kwargs: Additional deletion options.
|
|
157
|
+
|
|
158
|
+
Returns:
|
|
159
|
+
Any: Deletion result.
|
|
160
|
+
|
|
161
|
+
Raises:
|
|
162
|
+
NotImplementedError: If delete is not supported.
|
|
163
|
+
"""
|
|
164
|
+
raise NotImplementedError("This module does not support 'delete'")
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
"""
|
|
2
|
+
API client for communicating with xpander.ai services.
|
|
3
|
+
|
|
4
|
+
This module provides the core HTTP client functionality for making authenticated
|
|
5
|
+
requests to the xpander.ai Backend-as-a-Service platform.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
from abc import ABC
|
|
9
|
+
from typing import Optional, Any, Literal, Dict
|
|
10
|
+
import httpx
|
|
11
|
+
from pydantic import BaseModel
|
|
12
|
+
|
|
13
|
+
from xpander_sdk.models.configuration import Configuration
|
|
14
|
+
|
|
15
|
+
# Type alias for supported HTTP methods
|
|
16
|
+
HTTPMethod = Literal["GET", "POST", "PUT", "PATCH", "DELETE", "HEAD", "OPTIONS"]
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
class APIClient(ABC):
|
|
20
|
+
"""
|
|
21
|
+
Conditional singleton HTTP client for xpander.ai API communication.
|
|
22
|
+
|
|
23
|
+
- If no configuration is passed, uses a shared singleton instance.
|
|
24
|
+
- If a configuration is passed, creates a unique instance.
|
|
25
|
+
|
|
26
|
+
This client handles:
|
|
27
|
+
- API key authentication via x-api-key header
|
|
28
|
+
- URL construction
|
|
29
|
+
- JSON serialization/deserialization
|
|
30
|
+
- Extended timeouts
|
|
31
|
+
- HTTP error handling
|
|
32
|
+
"""
|
|
33
|
+
|
|
34
|
+
_shared_instances: Dict[type, 'APIClient'] = {}
|
|
35
|
+
|
|
36
|
+
def __new__(cls, configuration: Optional[Configuration] = None):
|
|
37
|
+
"""
|
|
38
|
+
Returns a shared singleton if no configuration is passed.
|
|
39
|
+
If configuration is provided, returns a unique instance.
|
|
40
|
+
"""
|
|
41
|
+
if configuration is not None:
|
|
42
|
+
instance = super().__new__(cls)
|
|
43
|
+
instance._is_custom_instance = True
|
|
44
|
+
return instance
|
|
45
|
+
|
|
46
|
+
if cls not in cls._shared_instances:
|
|
47
|
+
instance = super().__new__(cls)
|
|
48
|
+
instance._is_custom_instance = False
|
|
49
|
+
cls._shared_instances[cls] = instance
|
|
50
|
+
|
|
51
|
+
return cls._shared_instances[cls]
|
|
52
|
+
|
|
53
|
+
def __init__(self, configuration: Optional[Configuration] = None):
|
|
54
|
+
"""
|
|
55
|
+
Initialize the APIClient with configuration, once per instance.
|
|
56
|
+
"""
|
|
57
|
+
if hasattr(self, '_initialized') and self._initialized:
|
|
58
|
+
return
|
|
59
|
+
|
|
60
|
+
self.configuration = configuration or Configuration()
|
|
61
|
+
self._initialized = True
|
|
62
|
+
|
|
63
|
+
async def make_request(
|
|
64
|
+
self,
|
|
65
|
+
path: str,
|
|
66
|
+
method: HTTPMethod = "GET",
|
|
67
|
+
payload: Optional[Any] = None,
|
|
68
|
+
query: Optional[Dict[str, Any]] = None,
|
|
69
|
+
headers: Optional[Dict[str, Any]] = None,
|
|
70
|
+
configuration: Optional[Configuration] = None,
|
|
71
|
+
model: Optional[BaseModel] = None,
|
|
72
|
+
) -> Any:
|
|
73
|
+
"""
|
|
74
|
+
Make an authenticated HTTP request to the xpander.ai API.
|
|
75
|
+
|
|
76
|
+
Args:
|
|
77
|
+
path (str): Endpoint path (e.g., "/agents").
|
|
78
|
+
method (HTTPMethod): HTTP verb.
|
|
79
|
+
payload (Optional[Any]): JSON body for POST/PUT/PATCH.
|
|
80
|
+
query (Optional[Dict[str, Any]]): Query string parameters.
|
|
81
|
+
headers (Optional[Dict[str, Any]]): Extra headers.
|
|
82
|
+
configuration (Optional[Configuration]): Overrides self.configuration.
|
|
83
|
+
model (Optional[BaseModel]): pydantic model to use when constructing the result.
|
|
84
|
+
|
|
85
|
+
Returns:
|
|
86
|
+
Any: Parsed response body (JSON or text).
|
|
87
|
+
|
|
88
|
+
Raises:
|
|
89
|
+
httpx.HTTPStatusError: For 4xx/5xx responses.
|
|
90
|
+
httpx.RequestError: For connection/network errors.
|
|
91
|
+
"""
|
|
92
|
+
config = configuration or self.configuration
|
|
93
|
+
|
|
94
|
+
# Construct full URL
|
|
95
|
+
url = f"{config.get_full_url().rstrip('/')}/{path.lstrip('/')}"
|
|
96
|
+
|
|
97
|
+
# Prepare headers
|
|
98
|
+
headers = headers.copy() if headers else {}
|
|
99
|
+
headers["x-api-key"] = config.api_key
|
|
100
|
+
|
|
101
|
+
async with httpx.AsyncClient() as client:
|
|
102
|
+
response = await client.request(
|
|
103
|
+
method=method,
|
|
104
|
+
url=url,
|
|
105
|
+
json=payload if method in {"POST", "PUT", "PATCH"} else None,
|
|
106
|
+
params=query,
|
|
107
|
+
headers=headers,
|
|
108
|
+
timeout=1200, # 20 minutes
|
|
109
|
+
)
|
|
110
|
+
|
|
111
|
+
response.raise_for_status()
|
|
112
|
+
|
|
113
|
+
content_type = response.headers.get("Content-Type", "")
|
|
114
|
+
if "application/json" in content_type:
|
|
115
|
+
try:
|
|
116
|
+
return response.json() if not model else model(**response.json())
|
|
117
|
+
except Exception:
|
|
118
|
+
return response.text
|
|
119
|
+
return response.text
|
|
File without changes
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Custom exception classes for the xpander.ai SDK.
|
|
3
|
+
|
|
4
|
+
This module defines SDK-specific exception types for better error handling
|
|
5
|
+
and debugging throughout the xpander.ai Backend-as-a-Service platform.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class ModuleException(Exception):
|
|
10
|
+
"""
|
|
11
|
+
Custom exception for xpander.ai SDK module operations.
|
|
12
|
+
|
|
13
|
+
This exception is raised when SDK modules encounter errors during API
|
|
14
|
+
operations, providing structured error information including HTTP status
|
|
15
|
+
codes and detailed error descriptions.
|
|
16
|
+
|
|
17
|
+
Attributes:
|
|
18
|
+
status_code (int): HTTP status code associated with the error.
|
|
19
|
+
description (str): Detailed description of the error.
|
|
20
|
+
|
|
21
|
+
Example:
|
|
22
|
+
>>> try:
|
|
23
|
+
... agents = Agents()
|
|
24
|
+
... agent = agents.get("invalid-id")
|
|
25
|
+
... except ModuleException as e:
|
|
26
|
+
... print(f"Error {e.status_code}: {e.description}")
|
|
27
|
+
... # Error 404: Agent not found
|
|
28
|
+
"""
|
|
29
|
+
|
|
30
|
+
def __init__(self, status_code: int, description: str):
|
|
31
|
+
"""
|
|
32
|
+
Initialize a ModuleException with status code and description.
|
|
33
|
+
|
|
34
|
+
Args:
|
|
35
|
+
status_code (int): HTTP status code representing the error type
|
|
36
|
+
(e.g., 404 for not found, 401 for unauthorized, 500 for server error).
|
|
37
|
+
description (str): Human-readable description of the error condition.
|
|
38
|
+
|
|
39
|
+
Example:
|
|
40
|
+
>>> raise ModuleException(404, "Agent with ID 'xyz' not found")
|
|
41
|
+
>>> raise ModuleException(401, "Invalid API key provided")
|
|
42
|
+
"""
|
|
43
|
+
self.status_code = status_code
|
|
44
|
+
self.description = description
|
|
45
|
+
super().__init__(f"[{status_code}] {description}")
|
|
File without changes
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
from datetime import datetime
|
|
2
|
+
from enum import Enum
|
|
3
|
+
from typing import Any, List, Literal, Optional, Union
|
|
4
|
+
|
|
5
|
+
from xpander_sdk.models.events import ToolCallRequestReasoning
|
|
6
|
+
from xpander_sdk.models.shared import XPanderSharedModel
|
|
7
|
+
from xpander_sdk.models.user import User
|
|
8
|
+
from xpander_sdk.modules.tools_repository.models.mcp import MCPOAuthGetTokenResponse
|
|
9
|
+
|
|
10
|
+
class AgentActivityThreadMessageContent(XPanderSharedModel):
|
|
11
|
+
text: Optional[str] = None
|
|
12
|
+
files: Optional[List[str]] = []
|
|
13
|
+
|
|
14
|
+
class AgentActivityThreadMessage(XPanderSharedModel):
|
|
15
|
+
id: str
|
|
16
|
+
created_at: datetime
|
|
17
|
+
role: Literal["user","agent"]
|
|
18
|
+
content: AgentActivityThreadMessageContent
|
|
19
|
+
|
|
20
|
+
class AgentActivityThreadToolCall(XPanderSharedModel):
|
|
21
|
+
id: str
|
|
22
|
+
created_at: datetime
|
|
23
|
+
tool_name: str
|
|
24
|
+
payload: Any
|
|
25
|
+
is_error: Optional[bool] = False
|
|
26
|
+
reasoning: Optional[ToolCallRequestReasoning] = None
|
|
27
|
+
result: Optional[Any] = None
|
|
28
|
+
|
|
29
|
+
class AgentActivityThreadReasoningType(str, Enum):
|
|
30
|
+
Think = "think"
|
|
31
|
+
Analyze = "analyze"
|
|
32
|
+
|
|
33
|
+
class AgentActivityThreadReasoning(XPanderSharedModel):
|
|
34
|
+
id: str
|
|
35
|
+
created_at: datetime
|
|
36
|
+
type: AgentActivityThreadReasoningType
|
|
37
|
+
title: str
|
|
38
|
+
confidence: float
|
|
39
|
+
thought: Optional[str] = None
|
|
40
|
+
action: Optional[str] = None
|
|
41
|
+
result: Optional[str] = None
|
|
42
|
+
analysis: Optional[str] = None
|
|
43
|
+
|
|
44
|
+
class AgentActivityThreadSubAgentTrigger(XPanderSharedModel):
|
|
45
|
+
id: str
|
|
46
|
+
created_at: datetime
|
|
47
|
+
agent_id: str
|
|
48
|
+
query: Optional[str] = None
|
|
49
|
+
files: Optional[List[str]] = []
|
|
50
|
+
reasoning: ToolCallRequestReasoning
|
|
51
|
+
|
|
52
|
+
class AgentActivityThreadAuth(MCPOAuthGetTokenResponse):
|
|
53
|
+
id: str
|
|
54
|
+
created_at: datetime
|
|
55
|
+
|
|
56
|
+
AgentActivityThreadMessageType = Union[AgentActivityThreadMessage, AgentActivityThreadToolCall, AgentActivityThreadReasoning, AgentActivityThreadSubAgentTrigger, AgentActivityThreadAuth]
|
|
57
|
+
class AgentActivityThread(XPanderSharedModel):
|
|
58
|
+
id: str
|
|
59
|
+
created_at: datetime
|
|
60
|
+
messages: List[AgentActivityThreadMessageType]
|
|
61
|
+
user: Optional[User] = None
|
|
62
|
+
|
|
63
|
+
class AgentActivityThreadListItem(XPanderSharedModel):
|
|
64
|
+
id: str
|
|
65
|
+
created_at: datetime
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Configuration model for xpander.ai SDK.
|
|
3
|
+
|
|
4
|
+
This module contains the Configuration class that manages SDK settings including
|
|
5
|
+
API credentials, base URLs, and organization information.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
from typing import Optional
|
|
9
|
+
from os import getenv
|
|
10
|
+
from pydantic import BaseModel, Field
|
|
11
|
+
|
|
12
|
+
from xpander_sdk.core.state import State
|
|
13
|
+
from xpander_sdk.utils.env import get_base_url
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
class Configuration(BaseModel):
|
|
17
|
+
"""
|
|
18
|
+
Configuration settings for the xpander.ai SDK.
|
|
19
|
+
|
|
20
|
+
This class manages all configuration parameters required to connect to the xpander.ai
|
|
21
|
+
Backend-as-a-Service platform, including authentication credentials and service endpoints.
|
|
22
|
+
|
|
23
|
+
Attributes:
|
|
24
|
+
api_key (Optional[str]): Your xpander.ai API key. Defaults to XPANDER_API_KEY environment variable.
|
|
25
|
+
base_url (Optional[str]): The base URL for xpander.ai API endpoints. Auto-detected from environment.
|
|
26
|
+
organization_id (Optional[str]): Your organization ID. Defaults to XPANDER_ORGANIZATION_ID environment variable.
|
|
27
|
+
|
|
28
|
+
Environment Variables:
|
|
29
|
+
XPANDER_API_KEY: Your API key for authentication
|
|
30
|
+
XPANDER_ORGANIZATION_ID: Your organization identifier
|
|
31
|
+
|
|
32
|
+
Example:
|
|
33
|
+
>>> config = Configuration(
|
|
34
|
+
... api_key="your-api-key",
|
|
35
|
+
... organization_id="your-org-id"
|
|
36
|
+
... )
|
|
37
|
+
>>> full_url = config.get_full_url()
|
|
38
|
+
"""
|
|
39
|
+
|
|
40
|
+
api_key: Optional[str] = Field(
|
|
41
|
+
default_factory=lambda: getenv(key="XPANDER_API_KEY"),
|
|
42
|
+
description="xpander.ai API key for authentication",
|
|
43
|
+
)
|
|
44
|
+
|
|
45
|
+
base_url: Optional[str] = Field(
|
|
46
|
+
default_factory=get_base_url,
|
|
47
|
+
description="Base URL for xpander.ai API endpoints"
|
|
48
|
+
)
|
|
49
|
+
|
|
50
|
+
agent_id: Optional[str] = Field(
|
|
51
|
+
default= None,
|
|
52
|
+
description="Agent ID To work on"
|
|
53
|
+
)
|
|
54
|
+
|
|
55
|
+
organization_id: Optional[str] = Field(
|
|
56
|
+
default_factory=lambda: getenv(key="XPANDER_ORGANIZATION_ID"),
|
|
57
|
+
description="Organization identifier for xpander.ai account",
|
|
58
|
+
)
|
|
59
|
+
|
|
60
|
+
state: Optional[State] = Field(
|
|
61
|
+
default_factory=State,
|
|
62
|
+
description="Configuration level in-memory state",
|
|
63
|
+
exclude=True, # This ensures it's excluded by default
|
|
64
|
+
)
|
|
65
|
+
|
|
66
|
+
def get_full_url(self) -> str:
|
|
67
|
+
"""
|
|
68
|
+
Construct the complete API URL including organization ID when required.
|
|
69
|
+
|
|
70
|
+
Some xpander.ai services require the organization ID to be included in the URL path.
|
|
71
|
+
This method automatically detects when this is needed and constructs the appropriate URL.
|
|
72
|
+
|
|
73
|
+
Returns:
|
|
74
|
+
str: The complete URL for API requests, with organization ID included if required.
|
|
75
|
+
|
|
76
|
+
Example:
|
|
77
|
+
>>> config = Configuration(base_url="https://inbound.xpander.ai", organization_id="org123")
|
|
78
|
+
>>> config.get_full_url()
|
|
79
|
+
'https://inbound.xpander.ai'
|
|
80
|
+
|
|
81
|
+
>>> config = Configuration(base_url="https://agent-controller.xpander.ai", organization_id="org123")
|
|
82
|
+
>>> config.get_full_url()
|
|
83
|
+
'https://agent-controller.xpander.ai/org123'
|
|
84
|
+
"""
|
|
85
|
+
should_add_organization_id_to_the_url = (
|
|
86
|
+
"agent-controller" in self.base_url or "9016" in self.base_url
|
|
87
|
+
)
|
|
88
|
+
|
|
89
|
+
if should_add_organization_id_to_the_url:
|
|
90
|
+
return f"{self.base_url}/{self.organization_id}"
|
|
91
|
+
|
|
92
|
+
return self.base_url
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
from enum import Enum
|
|
2
|
+
from typing import Any, List, Optional
|
|
3
|
+
|
|
4
|
+
from pydantic import Field
|
|
5
|
+
from xpander_sdk.models.shared import XPanderSharedModel
|
|
6
|
+
from datetime import datetime
|
|
7
|
+
|
|
8
|
+
class TaskStatus(str, Enum):
|
|
9
|
+
READY = "ready"
|
|
10
|
+
RUNNING = "running"
|
|
11
|
+
FAILED = "failed"
|
|
12
|
+
DONE = "done"
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
class Task(XPanderSharedModel):
|
|
16
|
+
id: str = Field(..., description="task id")
|
|
17
|
+
title: str = Field(..., description="Short task title, max 120 chars")
|
|
18
|
+
description: Optional[str] = Field(None, description="Optional short step description, max 120 chars")
|
|
19
|
+
status: TaskStatus = Field(..., description="Task status")
|
|
20
|
+
created_at: datetime = Field(..., description="Creation timestamp (ISO 8601)")
|
|
21
|
+
started_at: Optional[datetime] = Field(None, description="Start timestamp (ISO 8601)")
|
|
22
|
+
finished_at: Optional[datetime] = Field(None, description="Finish timestamp (ISO 8601)")
|
|
23
|
+
error: Optional[str] = Field(None, description="Error message if failed")
|
|
24
|
+
parent_id: Optional[str] = Field(None, description="Parent task id if related")
|
|
25
|
+
|
|
26
|
+
class ToolCallRequestReasoning(XPanderSharedModel):
|
|
27
|
+
title: Optional[str] = None
|
|
28
|
+
description: Optional[str] = None
|
|
29
|
+
|
|
30
|
+
class ToolCallRequest(XPanderSharedModel):
|
|
31
|
+
request_id: str
|
|
32
|
+
operation_id: str
|
|
33
|
+
tool_call_id: Optional[str] = None
|
|
34
|
+
graph_node_id: Optional[str] = None
|
|
35
|
+
tool_name: Optional[str] = None
|
|
36
|
+
payload: Optional[Any] = None
|
|
37
|
+
reasoning: Optional[ToolCallRequestReasoning] = None
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
class ToolCallResult(ToolCallRequest):
|
|
41
|
+
operation_id: str
|
|
42
|
+
tool_call_id: Optional[str] = None
|
|
43
|
+
tool_name: Optional[str] = None
|
|
44
|
+
payload: Optional[Any] = None
|
|
45
|
+
result: Optional[Any] = None
|
|
46
|
+
is_error: Optional[bool] = False
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
class TaskUpdateEventType(str, Enum):
|
|
50
|
+
# tasks
|
|
51
|
+
TaskCreated = "task_created"
|
|
52
|
+
TaskUpdated = "task_updated"
|
|
53
|
+
TaskFinished = "task_finished"
|
|
54
|
+
|
|
55
|
+
# streaming
|
|
56
|
+
Chunk = "chunk"
|
|
57
|
+
|
|
58
|
+
# MCP Auth
|
|
59
|
+
AuthEvent = "auth_event"
|
|
60
|
+
|
|
61
|
+
# tool calls
|
|
62
|
+
ToolCallRequest = "tool_call_request"
|
|
63
|
+
ToolCallResult = "tool_call_result"
|
|
64
|
+
|
|
65
|
+
# multi agents
|
|
66
|
+
SubAgentTrigger = "sub_agent_trigger"
|
|
67
|
+
|
|
68
|
+
# reasoning
|
|
69
|
+
Think = "think"
|
|
70
|
+
Analyze = "analyze"
|