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.
Files changed (90) hide show
  1. xpander_sdk/__init__.py +76 -7793
  2. xpander_sdk/consts/__init__.py +0 -0
  3. xpander_sdk/consts/api_routes.py +63 -0
  4. xpander_sdk/core/__init__.py +0 -0
  5. xpander_sdk/core/module_base.py +164 -0
  6. xpander_sdk/core/state.py +10 -0
  7. xpander_sdk/core/xpander_api_client.py +119 -0
  8. xpander_sdk/exceptions/__init__.py +0 -0
  9. xpander_sdk/exceptions/module_exception.py +45 -0
  10. xpander_sdk/models/__init__.py +0 -0
  11. xpander_sdk/models/activity.py +65 -0
  12. xpander_sdk/models/configuration.py +92 -0
  13. xpander_sdk/models/events.py +70 -0
  14. xpander_sdk/models/frameworks.py +64 -0
  15. xpander_sdk/models/shared.py +102 -0
  16. xpander_sdk/models/user.py +21 -0
  17. xpander_sdk/modules/__init__.py +0 -0
  18. xpander_sdk/modules/agents/__init__.py +0 -0
  19. xpander_sdk/modules/agents/agents_module.py +164 -0
  20. xpander_sdk/modules/agents/models/__init__.py +0 -0
  21. xpander_sdk/modules/agents/models/agent.py +477 -0
  22. xpander_sdk/modules/agents/models/agent_list.py +107 -0
  23. xpander_sdk/modules/agents/models/knowledge_bases.py +33 -0
  24. xpander_sdk/modules/agents/sub_modules/__init__.py +0 -0
  25. xpander_sdk/modules/agents/sub_modules/agent.py +953 -0
  26. xpander_sdk/modules/agents/utils/__init__.py +0 -0
  27. xpander_sdk/modules/agents/utils/generic.py +2 -0
  28. xpander_sdk/modules/backend/__init__.py +0 -0
  29. xpander_sdk/modules/backend/backend_module.py +425 -0
  30. xpander_sdk/modules/backend/frameworks/__init__.py +0 -0
  31. xpander_sdk/modules/backend/frameworks/agno.py +627 -0
  32. xpander_sdk/modules/backend/frameworks/dispatch.py +36 -0
  33. xpander_sdk/modules/backend/utils/__init__.py +0 -0
  34. xpander_sdk/modules/backend/utils/mcp_oauth.py +95 -0
  35. xpander_sdk/modules/events/__init__.py +0 -0
  36. xpander_sdk/modules/events/decorators/__init__.py +0 -0
  37. xpander_sdk/modules/events/decorators/on_boot.py +94 -0
  38. xpander_sdk/modules/events/decorators/on_shutdown.py +94 -0
  39. xpander_sdk/modules/events/decorators/on_task.py +203 -0
  40. xpander_sdk/modules/events/events_module.py +629 -0
  41. xpander_sdk/modules/events/models/__init__.py +0 -0
  42. xpander_sdk/modules/events/models/deployments.py +25 -0
  43. xpander_sdk/modules/events/models/events.py +57 -0
  44. xpander_sdk/modules/events/utils/__init__.py +0 -0
  45. xpander_sdk/modules/events/utils/generic.py +56 -0
  46. xpander_sdk/modules/events/utils/git_init.py +32 -0
  47. xpander_sdk/modules/knowledge_bases/__init__.py +0 -0
  48. xpander_sdk/modules/knowledge_bases/knowledge_bases_module.py +217 -0
  49. xpander_sdk/modules/knowledge_bases/models/__init__.py +0 -0
  50. xpander_sdk/modules/knowledge_bases/models/knowledge_bases.py +11 -0
  51. xpander_sdk/modules/knowledge_bases/sub_modules/__init__.py +0 -0
  52. xpander_sdk/modules/knowledge_bases/sub_modules/knowledge_base.py +107 -0
  53. xpander_sdk/modules/knowledge_bases/sub_modules/knowledge_base_document_item.py +40 -0
  54. xpander_sdk/modules/knowledge_bases/utils/__init__.py +0 -0
  55. xpander_sdk/modules/tasks/__init__.py +0 -0
  56. xpander_sdk/modules/tasks/models/__init__.py +0 -0
  57. xpander_sdk/modules/tasks/models/task.py +153 -0
  58. xpander_sdk/modules/tasks/models/tasks_list.py +107 -0
  59. xpander_sdk/modules/tasks/sub_modules/__init__.py +0 -0
  60. xpander_sdk/modules/tasks/sub_modules/task.py +887 -0
  61. xpander_sdk/modules/tasks/tasks_module.py +492 -0
  62. xpander_sdk/modules/tasks/utils/__init__.py +0 -0
  63. xpander_sdk/modules/tasks/utils/files.py +114 -0
  64. xpander_sdk/modules/tools_repository/__init__.py +0 -0
  65. xpander_sdk/modules/tools_repository/decorators/__init__.py +0 -0
  66. xpander_sdk/modules/tools_repository/decorators/register_tool.py +108 -0
  67. xpander_sdk/modules/tools_repository/models/__init__.py +0 -0
  68. xpander_sdk/modules/tools_repository/models/mcp.py +68 -0
  69. xpander_sdk/modules/tools_repository/models/tool_invocation_result.py +14 -0
  70. xpander_sdk/modules/tools_repository/sub_modules/__init__.py +0 -0
  71. xpander_sdk/modules/tools_repository/sub_modules/tool.py +578 -0
  72. xpander_sdk/modules/tools_repository/tools_repository_module.py +259 -0
  73. xpander_sdk/modules/tools_repository/utils/__init__.py +0 -0
  74. xpander_sdk/modules/tools_repository/utils/generic.py +57 -0
  75. xpander_sdk/modules/tools_repository/utils/local_tools.py +52 -0
  76. xpander_sdk/modules/tools_repository/utils/schemas.py +308 -0
  77. xpander_sdk/utils/__init__.py +0 -0
  78. xpander_sdk/utils/env.py +44 -0
  79. xpander_sdk/utils/event_loop.py +67 -0
  80. xpander_sdk/utils/tools.py +32 -0
  81. xpander_sdk-2.0.155.dist-info/METADATA +538 -0
  82. xpander_sdk-2.0.155.dist-info/RECORD +85 -0
  83. {xpander_sdk-1.60.8.dist-info → xpander_sdk-2.0.155.dist-info}/WHEEL +1 -1
  84. {xpander_sdk-1.60.8.dist-info → xpander_sdk-2.0.155.dist-info/licenses}/LICENSE +0 -1
  85. xpander_sdk/_jsii/__init__.py +0 -39
  86. xpander_sdk/_jsii/xpander-sdk@1.60.8.jsii.tgz +0 -0
  87. xpander_sdk/py.typed +0 -1
  88. xpander_sdk-1.60.8.dist-info/METADATA +0 -368
  89. xpander_sdk-1.60.8.dist-info/RECORD +0 -9
  90. {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,10 @@
1
+ from asyncio import Task
2
+ from typing import Any, Optional
3
+
4
+
5
+ from xpander_sdk.models.shared import XPanderSharedModel
6
+
7
+
8
+ class State(XPanderSharedModel):
9
+ task: Optional[Any] = None
10
+ agent: Optional[Any] = None
@@ -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"