xpander-sdk 2.0.108__tar.gz → 2.0.157__tar.gz

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 (100) hide show
  1. {xpander_sdk-2.0.108 → xpander_sdk-2.0.157}/PKG-INFO +136 -7
  2. {xpander_sdk-2.0.108 → xpander_sdk-2.0.157}/README.md +131 -6
  3. {xpander_sdk-2.0.108 → xpander_sdk-2.0.157}/setup.py +4 -2
  4. {xpander_sdk-2.0.108 → xpander_sdk-2.0.157}/src/xpander_sdk/consts/api_routes.py +5 -0
  5. {xpander_sdk-2.0.108 → xpander_sdk-2.0.157}/src/xpander_sdk/core/xpander_api_client.py +4 -1
  6. xpander_sdk-2.0.157/src/xpander_sdk/models/activity.py +65 -0
  7. {xpander_sdk-2.0.108 → xpander_sdk-2.0.157}/src/xpander_sdk/models/configuration.py +5 -0
  8. {xpander_sdk-2.0.108 → xpander_sdk-2.0.157}/src/xpander_sdk/models/events.py +3 -0
  9. {xpander_sdk-2.0.108 → xpander_sdk-2.0.157}/src/xpander_sdk/models/frameworks.py +17 -1
  10. {xpander_sdk-2.0.108 → xpander_sdk-2.0.157}/src/xpander_sdk/models/shared.py +4 -0
  11. {xpander_sdk-2.0.108 → xpander_sdk-2.0.157}/src/xpander_sdk/modules/agents/agents_module.py +15 -7
  12. {xpander_sdk-2.0.108 → xpander_sdk-2.0.157}/src/xpander_sdk/modules/agents/models/agent.py +53 -1
  13. {xpander_sdk-2.0.108 → xpander_sdk-2.0.157}/src/xpander_sdk/modules/agents/sub_modules/agent.py +81 -5
  14. {xpander_sdk-2.0.108 → xpander_sdk-2.0.157}/src/xpander_sdk/modules/backend/backend_module.py +2 -2
  15. {xpander_sdk-2.0.108 → xpander_sdk-2.0.157}/src/xpander_sdk/modules/backend/frameworks/agno.py +130 -20
  16. {xpander_sdk-2.0.108 → xpander_sdk-2.0.157}/src/xpander_sdk/modules/backend/frameworks/dispatch.py +2 -1
  17. xpander_sdk-2.0.157/src/xpander_sdk/modules/backend/utils/mcp_oauth.py +95 -0
  18. {xpander_sdk-2.0.108 → xpander_sdk-2.0.157}/src/xpander_sdk/modules/events/events_module.py +15 -2
  19. {xpander_sdk-2.0.108 → xpander_sdk-2.0.157}/src/xpander_sdk/modules/tasks/sub_modules/task.py +165 -77
  20. {xpander_sdk-2.0.108 → xpander_sdk-2.0.157}/src/xpander_sdk/modules/tasks/tasks_module.py +8 -2
  21. {xpander_sdk-2.0.108 → xpander_sdk-2.0.157}/src/xpander_sdk/modules/tasks/utils/files.py +5 -2
  22. xpander_sdk-2.0.157/src/xpander_sdk/modules/tools_repository/models/mcp.py +68 -0
  23. {xpander_sdk-2.0.108 → xpander_sdk-2.0.157}/src/xpander_sdk/modules/tools_repository/tools_repository_module.py +11 -4
  24. {xpander_sdk-2.0.108 → xpander_sdk-2.0.157}/src/xpander_sdk/modules/tools_repository/utils/schemas.py +51 -13
  25. xpander_sdk-2.0.157/src/xpander_sdk/utils/__init__.py +0 -0
  26. xpander_sdk-2.0.157/src/xpander_sdk/utils/tools.py +32 -0
  27. {xpander_sdk-2.0.108 → xpander_sdk-2.0.157}/src/xpander_sdk.egg-info/PKG-INFO +136 -7
  28. {xpander_sdk-2.0.108 → xpander_sdk-2.0.157}/src/xpander_sdk.egg-info/SOURCES.txt +4 -0
  29. {xpander_sdk-2.0.108 → xpander_sdk-2.0.157}/src/xpander_sdk.egg-info/requires.txt +4 -0
  30. xpander_sdk-2.0.108/src/xpander_sdk/modules/tools_repository/models/mcp.py +0 -31
  31. {xpander_sdk-2.0.108 → xpander_sdk-2.0.157}/LICENSE +0 -0
  32. {xpander_sdk-2.0.108 → xpander_sdk-2.0.157}/pyproject.toml +0 -0
  33. {xpander_sdk-2.0.108 → xpander_sdk-2.0.157}/setup.cfg +0 -0
  34. {xpander_sdk-2.0.108 → xpander_sdk-2.0.157}/src/xpander_sdk/__init__.py +0 -0
  35. {xpander_sdk-2.0.108 → xpander_sdk-2.0.157}/src/xpander_sdk/consts/__init__.py +0 -0
  36. {xpander_sdk-2.0.108 → xpander_sdk-2.0.157}/src/xpander_sdk/core/__init__.py +0 -0
  37. {xpander_sdk-2.0.108 → xpander_sdk-2.0.157}/src/xpander_sdk/core/module_base.py +0 -0
  38. {xpander_sdk-2.0.108 → xpander_sdk-2.0.157}/src/xpander_sdk/core/state.py +0 -0
  39. {xpander_sdk-2.0.108 → xpander_sdk-2.0.157}/src/xpander_sdk/exceptions/__init__.py +0 -0
  40. {xpander_sdk-2.0.108 → xpander_sdk-2.0.157}/src/xpander_sdk/exceptions/module_exception.py +0 -0
  41. {xpander_sdk-2.0.108 → xpander_sdk-2.0.157}/src/xpander_sdk/models/__init__.py +0 -0
  42. {xpander_sdk-2.0.108 → xpander_sdk-2.0.157}/src/xpander_sdk/models/user.py +0 -0
  43. {xpander_sdk-2.0.108 → xpander_sdk-2.0.157}/src/xpander_sdk/modules/__init__.py +0 -0
  44. {xpander_sdk-2.0.108 → xpander_sdk-2.0.157}/src/xpander_sdk/modules/agents/__init__.py +0 -0
  45. {xpander_sdk-2.0.108 → xpander_sdk-2.0.157}/src/xpander_sdk/modules/agents/models/__init__.py +0 -0
  46. {xpander_sdk-2.0.108 → xpander_sdk-2.0.157}/src/xpander_sdk/modules/agents/models/agent_list.py +0 -0
  47. {xpander_sdk-2.0.108 → xpander_sdk-2.0.157}/src/xpander_sdk/modules/agents/models/knowledge_bases.py +0 -0
  48. {xpander_sdk-2.0.108 → xpander_sdk-2.0.157}/src/xpander_sdk/modules/agents/sub_modules/__init__.py +0 -0
  49. {xpander_sdk-2.0.108 → xpander_sdk-2.0.157}/src/xpander_sdk/modules/agents/utils/__init__.py +0 -0
  50. {xpander_sdk-2.0.108 → xpander_sdk-2.0.157}/src/xpander_sdk/modules/agents/utils/generic.py +0 -0
  51. {xpander_sdk-2.0.108 → xpander_sdk-2.0.157}/src/xpander_sdk/modules/backend/__init__.py +0 -0
  52. {xpander_sdk-2.0.108 → xpander_sdk-2.0.157}/src/xpander_sdk/modules/backend/frameworks/__init__.py +0 -0
  53. {xpander_sdk-2.0.108/src/xpander_sdk/modules/events → xpander_sdk-2.0.157/src/xpander_sdk/modules/backend/utils}/__init__.py +0 -0
  54. {xpander_sdk-2.0.108/src/xpander_sdk/modules/events/decorators → xpander_sdk-2.0.157/src/xpander_sdk/modules/events}/__init__.py +0 -0
  55. {xpander_sdk-2.0.108/src/xpander_sdk/modules/events/models → xpander_sdk-2.0.157/src/xpander_sdk/modules/events/decorators}/__init__.py +0 -0
  56. {xpander_sdk-2.0.108 → xpander_sdk-2.0.157}/src/xpander_sdk/modules/events/decorators/on_boot.py +0 -0
  57. {xpander_sdk-2.0.108 → xpander_sdk-2.0.157}/src/xpander_sdk/modules/events/decorators/on_shutdown.py +0 -0
  58. {xpander_sdk-2.0.108 → xpander_sdk-2.0.157}/src/xpander_sdk/modules/events/decorators/on_task.py +0 -0
  59. {xpander_sdk-2.0.108/src/xpander_sdk/modules/events/utils → xpander_sdk-2.0.157/src/xpander_sdk/modules/events/models}/__init__.py +0 -0
  60. {xpander_sdk-2.0.108 → xpander_sdk-2.0.157}/src/xpander_sdk/modules/events/models/deployments.py +0 -0
  61. {xpander_sdk-2.0.108 → xpander_sdk-2.0.157}/src/xpander_sdk/modules/events/models/events.py +0 -0
  62. {xpander_sdk-2.0.108/src/xpander_sdk/modules/knowledge_bases → xpander_sdk-2.0.157/src/xpander_sdk/modules/events/utils}/__init__.py +0 -0
  63. {xpander_sdk-2.0.108 → xpander_sdk-2.0.157}/src/xpander_sdk/modules/events/utils/generic.py +0 -0
  64. {xpander_sdk-2.0.108 → xpander_sdk-2.0.157}/src/xpander_sdk/modules/events/utils/git_init.py +0 -0
  65. {xpander_sdk-2.0.108/src/xpander_sdk/modules/knowledge_bases/models → xpander_sdk-2.0.157/src/xpander_sdk/modules/knowledge_bases}/__init__.py +0 -0
  66. {xpander_sdk-2.0.108 → xpander_sdk-2.0.157}/src/xpander_sdk/modules/knowledge_bases/knowledge_bases_module.py +0 -0
  67. {xpander_sdk-2.0.108/src/xpander_sdk/modules/knowledge_bases/sub_modules → xpander_sdk-2.0.157/src/xpander_sdk/modules/knowledge_bases/models}/__init__.py +0 -0
  68. {xpander_sdk-2.0.108 → xpander_sdk-2.0.157}/src/xpander_sdk/modules/knowledge_bases/models/knowledge_bases.py +0 -0
  69. {xpander_sdk-2.0.108/src/xpander_sdk/modules/knowledge_bases/utils → xpander_sdk-2.0.157/src/xpander_sdk/modules/knowledge_bases/sub_modules}/__init__.py +0 -0
  70. {xpander_sdk-2.0.108 → xpander_sdk-2.0.157}/src/xpander_sdk/modules/knowledge_bases/sub_modules/knowledge_base.py +0 -0
  71. {xpander_sdk-2.0.108 → xpander_sdk-2.0.157}/src/xpander_sdk/modules/knowledge_bases/sub_modules/knowledge_base_document_item.py +0 -0
  72. {xpander_sdk-2.0.108/src/xpander_sdk/modules/tasks → xpander_sdk-2.0.157/src/xpander_sdk/modules/knowledge_bases/utils}/__init__.py +0 -0
  73. {xpander_sdk-2.0.108/src/xpander_sdk/modules/tasks/models → xpander_sdk-2.0.157/src/xpander_sdk/modules/tasks}/__init__.py +0 -0
  74. {xpander_sdk-2.0.108/src/xpander_sdk/modules/tasks/sub_modules → xpander_sdk-2.0.157/src/xpander_sdk/modules/tasks/models}/__init__.py +0 -0
  75. {xpander_sdk-2.0.108 → xpander_sdk-2.0.157}/src/xpander_sdk/modules/tasks/models/task.py +0 -0
  76. {xpander_sdk-2.0.108 → xpander_sdk-2.0.157}/src/xpander_sdk/modules/tasks/models/tasks_list.py +0 -0
  77. {xpander_sdk-2.0.108/src/xpander_sdk/modules/tasks/utils → xpander_sdk-2.0.157/src/xpander_sdk/modules/tasks/sub_modules}/__init__.py +0 -0
  78. {xpander_sdk-2.0.108/src/xpander_sdk/modules/tools_repository → xpander_sdk-2.0.157/src/xpander_sdk/modules/tasks/utils}/__init__.py +0 -0
  79. {xpander_sdk-2.0.108/src/xpander_sdk/modules/tools_repository/decorators → xpander_sdk-2.0.157/src/xpander_sdk/modules/tools_repository}/__init__.py +0 -0
  80. {xpander_sdk-2.0.108/src/xpander_sdk/modules/tools_repository/models → xpander_sdk-2.0.157/src/xpander_sdk/modules/tools_repository/decorators}/__init__.py +0 -0
  81. {xpander_sdk-2.0.108 → xpander_sdk-2.0.157}/src/xpander_sdk/modules/tools_repository/decorators/register_tool.py +0 -0
  82. {xpander_sdk-2.0.108/src/xpander_sdk/modules/tools_repository/sub_modules → xpander_sdk-2.0.157/src/xpander_sdk/modules/tools_repository/models}/__init__.py +0 -0
  83. {xpander_sdk-2.0.108 → xpander_sdk-2.0.157}/src/xpander_sdk/modules/tools_repository/models/tool_invocation_result.py +0 -0
  84. {xpander_sdk-2.0.108/src/xpander_sdk/modules/tools_repository/utils → xpander_sdk-2.0.157/src/xpander_sdk/modules/tools_repository/sub_modules}/__init__.py +0 -0
  85. {xpander_sdk-2.0.108 → xpander_sdk-2.0.157}/src/xpander_sdk/modules/tools_repository/sub_modules/tool.py +0 -0
  86. {xpander_sdk-2.0.108/src/xpander_sdk → xpander_sdk-2.0.157/src/xpander_sdk/modules/tools_repository}/utils/__init__.py +0 -0
  87. {xpander_sdk-2.0.108 → xpander_sdk-2.0.157}/src/xpander_sdk/modules/tools_repository/utils/generic.py +0 -0
  88. {xpander_sdk-2.0.108 → xpander_sdk-2.0.157}/src/xpander_sdk/modules/tools_repository/utils/local_tools.py +0 -0
  89. {xpander_sdk-2.0.108 → xpander_sdk-2.0.157}/src/xpander_sdk/utils/env.py +0 -0
  90. {xpander_sdk-2.0.108 → xpander_sdk-2.0.157}/src/xpander_sdk/utils/event_loop.py +0 -0
  91. {xpander_sdk-2.0.108 → xpander_sdk-2.0.157}/src/xpander_sdk.egg-info/dependency_links.txt +0 -0
  92. {xpander_sdk-2.0.108 → xpander_sdk-2.0.157}/src/xpander_sdk.egg-info/top_level.txt +0 -0
  93. {xpander_sdk-2.0.108 → xpander_sdk-2.0.157}/tests/test_agents_module.py +0 -0
  94. {xpander_sdk-2.0.108 → xpander_sdk-2.0.157}/tests/test_api_client.py +0 -0
  95. {xpander_sdk-2.0.108 → xpander_sdk-2.0.157}/tests/test_backend_module.py +0 -0
  96. {xpander_sdk-2.0.108 → xpander_sdk-2.0.157}/tests/test_boot_shutdown_handlers.py +0 -0
  97. {xpander_sdk-2.0.108 → xpander_sdk-2.0.157}/tests/test_configuration.py +0 -0
  98. {xpander_sdk-2.0.108 → xpander_sdk-2.0.157}/tests/test_knowledge_bases_module.py +0 -0
  99. {xpander_sdk-2.0.108 → xpander_sdk-2.0.157}/tests/test_tasks_module.py +0 -0
  100. {xpander_sdk-2.0.108 → xpander_sdk-2.0.157}/tests/test_tools_repository.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: xpander-sdk
3
- Version: 2.0.108
3
+ Version: 2.0.157
4
4
  Summary: xpander.ai Backend-as-a-service for AI Agents - SDK
5
5
  Home-page: https://www.xpander.ai
6
6
  Author: xpanderAI
@@ -18,6 +18,8 @@ Requires-Dist: loguru
18
18
  Requires-Dist: httpx
19
19
  Requires-Dist: httpx_sse
20
20
  Requires-Dist: nest-asyncio
21
+ Requires-Dist: strands-agents
22
+ Requires-Dist: openai-agents
21
23
  Provides-Extra: agno
22
24
  Requires-Dist: agno; extra == "agno"
23
25
  Requires-Dist: sqlalchemy; extra == "agno"
@@ -31,6 +33,8 @@ Requires-Dist: anthropic; extra == "dev"
31
33
  Requires-Dist: mcp; extra == "dev"
32
34
  Requires-Dist: openai; extra == "dev"
33
35
  Requires-Dist: fireworks-ai; extra == "dev"
36
+ Requires-Dist: aioboto3; extra == "dev"
37
+ Requires-Dist: google-genai; extra == "dev"
34
38
  Dynamic: author
35
39
  Dynamic: author-email
36
40
  Dynamic: classifier
@@ -47,7 +51,6 @@ Dynamic: summary
47
51
 
48
52
  [![Python 3.9+](https://img.shields.io/badge/python-3.9+-blue.svg)](https://www.python.org/downloads/) [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT) [![Documentation](https://img.shields.io/badge/docs-available-brightgreen.svg)](https://docs.xpander.ai) [![PyPI Version](https://img.shields.io/pypi/v/xpander-sdk?label=PyPI)](https://pypi.org/project/xpander-sdk/) [![Downloads](https://pepy.tech/badge/xpander-sdk)](https://pepy.tech/project/xpander-sdk)
49
53
 
50
-
51
54
  The official Python SDK for xpander.ai - a powerful Backend-as-a-Service (BaaS) platform for building, deploying, and managing AI agents at scale.
52
55
 
53
56
  ## 🚀 Overview
@@ -128,6 +131,11 @@ tasks = Tasks(configuration=config)
128
131
  task = await tasks.aget("task-id")
129
132
  await task.aset_status(AgentExecutionStatus.Running)
130
133
  await task.asave()
134
+
135
+ # Retrieve task activity log
136
+ activity_log = await task.aget_activity_log()
137
+ for message in activity_log.messages:
138
+ print(f"{message.role}: {message.content.text}")
131
139
  ```
132
140
 
133
141
  ### 4. Tools Integration
@@ -284,6 +292,40 @@ async for event in task.aevents():
284
292
  print(f"Event Data: {event.data}")
285
293
  ```
286
294
 
295
+ ### Task Activity Monitoring
296
+
297
+ ```python
298
+ from xpander_sdk import Task
299
+ from xpander_sdk.models.activity import (
300
+ AgentActivityThreadMessage,
301
+ AgentActivityThreadToolCall,
302
+ AgentActivityThreadReasoning
303
+ )
304
+
305
+ # Load a completed task
306
+ task = await Task.aload("task-id")
307
+
308
+ # Get detailed activity log
309
+ activity_log = await task.aget_activity_log()
310
+
311
+ # Analyze messages between user and agent
312
+ for message in activity_log.messages:
313
+ if isinstance(message, AgentActivityThreadMessage):
314
+ print(f"{message.role}: {message.content.text}")
315
+ elif isinstance(message, AgentActivityThreadToolCall):
316
+ # Tool call
317
+ print(f"Tool: {message.tool_name}")
318
+ print(f"Payload: {message.payload}")
319
+ print(f"Result: {message.result}")
320
+ elif isinstance(message, AgentActivityThreadReasoning):
321
+ # Reasoning step
322
+ print(f"Reasoning ({message.type}): {message.thought}")
323
+
324
+ # Synchronous version
325
+ task = Task.load("task-id")
326
+ activity_log = task.get_activity_log()
327
+ ```
328
+
287
329
  ### Local Task Testing
288
330
 
289
331
  ```python
@@ -304,7 +346,7 @@ async def handle_test_task(task):
304
346
  task.result = {
305
347
  "capabilities": [
306
348
  "Data analysis",
307
- "Text processing",
349
+ "Text processing",
308
350
  "API integration"
309
351
  ]
310
352
  }
@@ -375,6 +417,93 @@ load_dotenv()
375
417
  config = Configuration()
376
418
  ```
377
419
 
420
+ ## 🏢 Self-Hosted Deployment
421
+
422
+ If you're using a self-hosted xpander.ai deployment, configure the SDK to point to your Agent Controller endpoint.
423
+
424
+ **Important**: Use the **Agent Controller API key** generated during Helm installation, not your xpander.ai cloud API key.
425
+
426
+ ### Configuration
427
+
428
+ ```bash
429
+ # Set environment variables
430
+ export XPANDER_API_KEY="your-agent-controller-api-key" # From Helm installation
431
+ export XPANDER_ORGANIZATION_ID="your-org-id"
432
+ export XPANDER_BASE_URL="https://agent-controller.my-company.com"
433
+ ```
434
+
435
+ Or configure explicitly:
436
+
437
+ ```python
438
+ from xpander_sdk import Configuration
439
+
440
+ config = Configuration(
441
+ api_key="your-agent-controller-api-key", # From Helm installation
442
+ organization_id="your-org-id",
443
+ base_url="https://agent-controller.my-company.com"
444
+ )
445
+ ```
446
+
447
+ ### Using with Agno Framework
448
+
449
+ ```python
450
+ from xpander_sdk import Backend, Configuration
451
+ from agno.agent import Agent
452
+
453
+ # Configure for self-hosted
454
+ config = Configuration(
455
+ api_key="your-agent-controller-api-key", # From Helm installation
456
+ organization_id="your-org-id",
457
+ base_url="https://agent-controller.my-company.com"
458
+ )
459
+
460
+ # Initialize Backend with self-hosted config
461
+ backend = Backend(configuration=config)
462
+
463
+ # Create agent - it will use your self-hosted infrastructure
464
+ agno_agent = Agent(**backend.get_args(agent_id="agent-123"))
465
+
466
+ # Run agent
467
+ result = await agno_agent.arun(
468
+ input="What can you help me with?",
469
+ stream=True
470
+ )
471
+ ```
472
+
473
+ ### Complete Self-Hosted Example
474
+
475
+ ```python
476
+ import asyncio
477
+ from xpander_sdk import Configuration, Agent
478
+
479
+ async def main():
480
+ # Configure for self-hosted deployment
481
+ config = Configuration(
482
+ api_key="your-agent-controller-api-key", # From Helm installation
483
+ organization_id="your-org-id",
484
+ base_url="https://agent-controller.my-company.com"
485
+ )
486
+
487
+ # Load agent from self-hosted deployment
488
+ agent = await Agent.aload("agent-123", configuration=config)
489
+ print(f"Agent: {agent.name}")
490
+
491
+ # Create and execute task
492
+ task = await agent.acreate_task(
493
+ prompt="Analyze Q4 sales data",
494
+ file_urls=["https://example.com/sales-q4.csv"]
495
+ )
496
+ print(f"Task created: {task.id}")
497
+ print(f"Status: {task.status}")
498
+
499
+ if __name__ == "__main__":
500
+ asyncio.run(main())
501
+ ```
502
+
503
+ **Important**: Make sure your `base_url` points to the Agent Controller endpoint (e.g., `https://agent-controller.{your-domain}`), not the root domain.
504
+
505
+ 📖 **Full Guide**: [Self-Hosted Configuration Documentation](https://docs.xpander.ai/api-reference/configuration/self-hosted)
506
+
378
507
  ## 🔄 Error Handling
379
508
 
380
509
  ```python
@@ -389,9 +518,9 @@ except ModuleException as e:
389
518
  ## 🤝 Contributing
390
519
 
391
520
  1. Fork the repository
392
- 2. Create a feature branch (`git checkout -b feature/amazing-feature`)
393
- 3. Commit your changes (`git commit -m 'Add amazing feature'`)
394
- 4. Push to the branch (`git push origin feature/amazing-feature`)
521
+ 2. Create a feature branch (`git checkout -b feature/{base_branch}/amazing-feature`)
522
+ 3. Commit your changes (`git commit -m 'feat/chore/fix: Add amazing feature'`)
523
+ 4. Push to the branch (`git push origin feature/{base_branch}/amazing-feature`)
395
524
  5. Open a Pull Request
396
525
 
397
526
  ## 📄 License
@@ -402,7 +531,7 @@ This project is licensed under the MIT License - see the LICENSE file for detail
402
531
 
403
532
  - **Documentation**: [https://docs.xpander.ai](https://docs.xpander.ai)
404
533
  - **Issues**: [GitHub Issues](https://github.com/xpander-ai/xpander-sdk/issues)
405
- - **Email**: dev@xpander.ai
534
+ - **Email**: support@xpander.ai
406
535
 
407
536
  ---
408
537
 
@@ -2,7 +2,6 @@
2
2
 
3
3
  [![Python 3.9+](https://img.shields.io/badge/python-3.9+-blue.svg)](https://www.python.org/downloads/) [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT) [![Documentation](https://img.shields.io/badge/docs-available-brightgreen.svg)](https://docs.xpander.ai) [![PyPI Version](https://img.shields.io/pypi/v/xpander-sdk?label=PyPI)](https://pypi.org/project/xpander-sdk/) [![Downloads](https://pepy.tech/badge/xpander-sdk)](https://pepy.tech/project/xpander-sdk)
4
4
 
5
-
6
5
  The official Python SDK for xpander.ai - a powerful Backend-as-a-Service (BaaS) platform for building, deploying, and managing AI agents at scale.
7
6
 
8
7
  ## 🚀 Overview
@@ -83,6 +82,11 @@ tasks = Tasks(configuration=config)
83
82
  task = await tasks.aget("task-id")
84
83
  await task.aset_status(AgentExecutionStatus.Running)
85
84
  await task.asave()
85
+
86
+ # Retrieve task activity log
87
+ activity_log = await task.aget_activity_log()
88
+ for message in activity_log.messages:
89
+ print(f"{message.role}: {message.content.text}")
86
90
  ```
87
91
 
88
92
  ### 4. Tools Integration
@@ -239,6 +243,40 @@ async for event in task.aevents():
239
243
  print(f"Event Data: {event.data}")
240
244
  ```
241
245
 
246
+ ### Task Activity Monitoring
247
+
248
+ ```python
249
+ from xpander_sdk import Task
250
+ from xpander_sdk.models.activity import (
251
+ AgentActivityThreadMessage,
252
+ AgentActivityThreadToolCall,
253
+ AgentActivityThreadReasoning
254
+ )
255
+
256
+ # Load a completed task
257
+ task = await Task.aload("task-id")
258
+
259
+ # Get detailed activity log
260
+ activity_log = await task.aget_activity_log()
261
+
262
+ # Analyze messages between user and agent
263
+ for message in activity_log.messages:
264
+ if isinstance(message, AgentActivityThreadMessage):
265
+ print(f"{message.role}: {message.content.text}")
266
+ elif isinstance(message, AgentActivityThreadToolCall):
267
+ # Tool call
268
+ print(f"Tool: {message.tool_name}")
269
+ print(f"Payload: {message.payload}")
270
+ print(f"Result: {message.result}")
271
+ elif isinstance(message, AgentActivityThreadReasoning):
272
+ # Reasoning step
273
+ print(f"Reasoning ({message.type}): {message.thought}")
274
+
275
+ # Synchronous version
276
+ task = Task.load("task-id")
277
+ activity_log = task.get_activity_log()
278
+ ```
279
+
242
280
  ### Local Task Testing
243
281
 
244
282
  ```python
@@ -259,7 +297,7 @@ async def handle_test_task(task):
259
297
  task.result = {
260
298
  "capabilities": [
261
299
  "Data analysis",
262
- "Text processing",
300
+ "Text processing",
263
301
  "API integration"
264
302
  ]
265
303
  }
@@ -330,6 +368,93 @@ load_dotenv()
330
368
  config = Configuration()
331
369
  ```
332
370
 
371
+ ## 🏢 Self-Hosted Deployment
372
+
373
+ If you're using a self-hosted xpander.ai deployment, configure the SDK to point to your Agent Controller endpoint.
374
+
375
+ **Important**: Use the **Agent Controller API key** generated during Helm installation, not your xpander.ai cloud API key.
376
+
377
+ ### Configuration
378
+
379
+ ```bash
380
+ # Set environment variables
381
+ export XPANDER_API_KEY="your-agent-controller-api-key" # From Helm installation
382
+ export XPANDER_ORGANIZATION_ID="your-org-id"
383
+ export XPANDER_BASE_URL="https://agent-controller.my-company.com"
384
+ ```
385
+
386
+ Or configure explicitly:
387
+
388
+ ```python
389
+ from xpander_sdk import Configuration
390
+
391
+ config = Configuration(
392
+ api_key="your-agent-controller-api-key", # From Helm installation
393
+ organization_id="your-org-id",
394
+ base_url="https://agent-controller.my-company.com"
395
+ )
396
+ ```
397
+
398
+ ### Using with Agno Framework
399
+
400
+ ```python
401
+ from xpander_sdk import Backend, Configuration
402
+ from agno.agent import Agent
403
+
404
+ # Configure for self-hosted
405
+ config = Configuration(
406
+ api_key="your-agent-controller-api-key", # From Helm installation
407
+ organization_id="your-org-id",
408
+ base_url="https://agent-controller.my-company.com"
409
+ )
410
+
411
+ # Initialize Backend with self-hosted config
412
+ backend = Backend(configuration=config)
413
+
414
+ # Create agent - it will use your self-hosted infrastructure
415
+ agno_agent = Agent(**backend.get_args(agent_id="agent-123"))
416
+
417
+ # Run agent
418
+ result = await agno_agent.arun(
419
+ input="What can you help me with?",
420
+ stream=True
421
+ )
422
+ ```
423
+
424
+ ### Complete Self-Hosted Example
425
+
426
+ ```python
427
+ import asyncio
428
+ from xpander_sdk import Configuration, Agent
429
+
430
+ async def main():
431
+ # Configure for self-hosted deployment
432
+ config = Configuration(
433
+ api_key="your-agent-controller-api-key", # From Helm installation
434
+ organization_id="your-org-id",
435
+ base_url="https://agent-controller.my-company.com"
436
+ )
437
+
438
+ # Load agent from self-hosted deployment
439
+ agent = await Agent.aload("agent-123", configuration=config)
440
+ print(f"Agent: {agent.name}")
441
+
442
+ # Create and execute task
443
+ task = await agent.acreate_task(
444
+ prompt="Analyze Q4 sales data",
445
+ file_urls=["https://example.com/sales-q4.csv"]
446
+ )
447
+ print(f"Task created: {task.id}")
448
+ print(f"Status: {task.status}")
449
+
450
+ if __name__ == "__main__":
451
+ asyncio.run(main())
452
+ ```
453
+
454
+ **Important**: Make sure your `base_url` points to the Agent Controller endpoint (e.g., `https://agent-controller.{your-domain}`), not the root domain.
455
+
456
+ 📖 **Full Guide**: [Self-Hosted Configuration Documentation](https://docs.xpander.ai/api-reference/configuration/self-hosted)
457
+
333
458
  ## 🔄 Error Handling
334
459
 
335
460
  ```python
@@ -344,9 +469,9 @@ except ModuleException as e:
344
469
  ## 🤝 Contributing
345
470
 
346
471
  1. Fork the repository
347
- 2. Create a feature branch (`git checkout -b feature/amazing-feature`)
348
- 3. Commit your changes (`git commit -m 'Add amazing feature'`)
349
- 4. Push to the branch (`git push origin feature/amazing-feature`)
472
+ 2. Create a feature branch (`git checkout -b feature/{base_branch}/amazing-feature`)
473
+ 3. Commit your changes (`git commit -m 'feat/chore/fix: Add amazing feature'`)
474
+ 4. Push to the branch (`git push origin feature/{base_branch}/amazing-feature`)
350
475
  5. Open a Pull Request
351
476
 
352
477
  ## 📄 License
@@ -357,7 +482,7 @@ This project is licensed under the MIT License - see the LICENSE file for detail
357
482
 
358
483
  - **Documentation**: [https://docs.xpander.ai](https://docs.xpander.ai)
359
484
  - **Issues**: [GitHub Issues](https://github.com/xpander-ai/xpander-sdk/issues)
360
- - **Email**: dev@xpander.ai
485
+ - **Email**: support@xpander.ai
361
486
 
362
487
  ---
363
488
 
@@ -5,7 +5,7 @@ with open("README.md", "r", encoding="utf-8") as fh:
5
5
 
6
6
  setup(
7
7
  name="xpander-sdk",
8
- version="2.0.108",
8
+ version="2.0.157",
9
9
  author="xpanderAI",
10
10
  author_email="dev@xpander.ai",
11
11
  description="xpander.ai Backend-as-a-service for AI Agents - SDK",
@@ -22,10 +22,12 @@ setup(
22
22
  "httpx",
23
23
  "httpx_sse",
24
24
  "nest-asyncio",
25
+ "strands-agents",
26
+ "openai-agents",
25
27
  ],
26
28
  extras_require={
27
29
  "agno": ["agno", "sqlalchemy" ,"psycopg[binary,pool]", "greenlet"],
28
- "dev": ["black", "pre-commit", "pytest", "anthropic", "mcp", "openai", "fireworks-ai"],
30
+ "dev": ["black", "pre-commit", "pytest", "anthropic", "mcp", "openai", "fireworks-ai", "aioboto3", "google-genai"],
29
31
  },
30
32
  classifiers=[
31
33
  "Programming Language :: Python :: 3",
@@ -35,10 +35,12 @@ and deleting resources.
35
35
  ListTasks = "/agent-execution/executions/history/{agent_id}"
36
36
  ListUserTasks = "/agent-execution/executions/history/user/{user_id}"
37
37
  GetTask = "/agent-execution/{task_id}/status"
38
+ GetTaskActivityLog = "/activity/{agent_id}/{task_id}"
38
39
  TaskCrud = "/agent-execution/{agent_or_task_id}"
39
40
  UpdateTask = "/agent-execution/{task_id}/update"
40
41
  ReportExternalTask = "/agent-execution/{agent_id}/report_task"
41
42
  ReportExecutionMetrics = "/agents-metrics/{agent_id}/execution"
43
+ PushExecutionEventToQueue = "/agent-execution/{task_id}/events/push"
42
44
 
43
45
  # Knowledge Bases Endpoints
44
46
  ListKnowledgeBases = "/knowledge_bases"
@@ -48,6 +50,9 @@ and deleting resources.
48
50
  KnowledgeBaseDocumentsCrud = "/knowledge_bases/{knowledge_base_id}"
49
51
  GetKnowledgeBaseDetails = "/knowledge_bases/{knowledge_base_id}/details"
50
52
 
53
+ # MCP Auth
54
+ GetUserMCPAuthToken = "/mcp_auth/{agent_id}/{user_id}/get_token"
55
+
51
56
  # Tools
52
57
  GetOrInvokeToolById = "/tools/{tool_id}"
53
58
 
@@ -8,6 +8,7 @@ requests to the xpander.ai Backend-as-a-Service platform.
8
8
  from abc import ABC
9
9
  from typing import Optional, Any, Literal, Dict
10
10
  import httpx
11
+ from pydantic import BaseModel
11
12
 
12
13
  from xpander_sdk.models.configuration import Configuration
13
14
 
@@ -67,6 +68,7 @@ class APIClient(ABC):
67
68
  query: Optional[Dict[str, Any]] = None,
68
69
  headers: Optional[Dict[str, Any]] = None,
69
70
  configuration: Optional[Configuration] = None,
71
+ model: Optional[BaseModel] = None,
70
72
  ) -> Any:
71
73
  """
72
74
  Make an authenticated HTTP request to the xpander.ai API.
@@ -78,6 +80,7 @@ class APIClient(ABC):
78
80
  query (Optional[Dict[str, Any]]): Query string parameters.
79
81
  headers (Optional[Dict[str, Any]]): Extra headers.
80
82
  configuration (Optional[Configuration]): Overrides self.configuration.
83
+ model (Optional[BaseModel]): pydantic model to use when constructing the result.
81
84
 
82
85
  Returns:
83
86
  Any: Parsed response body (JSON or text).
@@ -110,7 +113,7 @@ class APIClient(ABC):
110
113
  content_type = response.headers.get("Content-Type", "")
111
114
  if "application/json" in content_type:
112
115
  try:
113
- return response.json()
116
+ return response.json() if not model else model(**response.json())
114
117
  except Exception:
115
118
  return response.text
116
119
  return response.text
@@ -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
@@ -47,6 +47,11 @@ class Configuration(BaseModel):
47
47
  description="Base URL for xpander.ai API endpoints"
48
48
  )
49
49
 
50
+ agent_id: Optional[str] = Field(
51
+ default= None,
52
+ description="Agent ID To work on"
53
+ )
54
+
50
55
  organization_id: Optional[str] = Field(
51
56
  default_factory=lambda: getenv(key="XPANDER_ORGANIZATION_ID"),
52
57
  description="Organization identifier for xpander.ai account",
@@ -54,6 +54,9 @@ class TaskUpdateEventType(str, Enum):
54
54
 
55
55
  # streaming
56
56
  Chunk = "chunk"
57
+
58
+ # MCP Auth
59
+ AuthEvent = "auth_event"
57
60
 
58
61
  # tool calls
59
62
  ToolCallRequest = "tool_call_request"
@@ -12,7 +12,15 @@ class Framework(str, Enum):
12
12
  """
13
13
 
14
14
  Agno = "agno"
15
+ GoogleADK = "google-adk"
16
+ LangChain = "langchain"
17
+ OpenAIAgents = "open-ai-agents"
18
+ Strands = "strands-agents"
15
19
 
20
+ class AgnoToolCallsCompressionSettings(BaseModel):
21
+ enabled: Optional[bool] = False
22
+ threshold: Optional[int] = 3
23
+ instructions: Optional[str] = ""
16
24
 
17
25
  class AgnoSettings(BaseModel):
18
26
  """
@@ -34,7 +42,13 @@ class AgnoSettings(BaseModel):
34
42
  """
35
43
 
36
44
  session_storage: Optional[bool] = True
37
- user_memories: Optional[bool] = True
45
+
46
+ user_memories: Optional[bool] = False
47
+ agentic_memory: Optional[bool] = False
48
+
49
+ agent_memories: Optional[bool] = False
50
+ agentic_culture: Optional[bool] = False
51
+
38
52
  session_summaries: Optional[bool] = False
39
53
  num_history_runs: Optional[int] = 3
40
54
  max_tool_calls_from_history: Optional[int] = 0
@@ -46,3 +60,5 @@ class AgnoSettings(BaseModel):
46
60
  openai_moderation_enabled: Optional[bool] = False
47
61
  openai_moderation_categories: Optional[List[str]] = None
48
62
  reasoning_tools_enabled: Optional[bool] = False
63
+
64
+ tool_calls_compression: Optional[AgnoToolCallsCompressionSettings] = None
@@ -96,3 +96,7 @@ class Tokens(BaseModel):
96
96
  class ExecutionTokens(BaseModel):
97
97
  inner: Optional[Tokens] = Tokens()
98
98
  worker: Optional[Tokens] = Tokens()
99
+
100
+ class ThinkMode(str, Enum):
101
+ Default = "default"
102
+ Harder = "harder"
@@ -6,7 +6,7 @@ within the xpander.ai Backend-as-a-Service platform.
6
6
  """
7
7
 
8
8
  from typing import List, Optional
9
-
9
+ from os import getenv
10
10
  from httpx import HTTPStatusError
11
11
 
12
12
  from xpander_sdk.consts.api_routes import APIRoute
@@ -99,7 +99,7 @@ class Agents(ModuleBase):
99
99
  """
100
100
  return run_sync(self.alist())
101
101
 
102
- async def aget(self, agent_id: str, version: Optional[int] = None) -> Agent:
102
+ async def aget(self, agent_id: Optional[str] = None, version: Optional[int] = None) -> Agent:
103
103
  """
104
104
  Asynchronously retrieve a specific agent by ID.
105
105
 
@@ -108,7 +108,7 @@ class Agents(ModuleBase):
108
108
  a specific version of the agent.
109
109
 
110
110
  Args:
111
- agent_id (str): Unique identifier of the agent to retrieve.
111
+ agent_id (Optional[str]): Unique identifier of the agent to retrieve, Fallback to XPANDER_AGENT_ID.
112
112
  version (Optional[int]): Specific version number to load. If None,
113
113
  loads the latest version.
114
114
 
@@ -127,9 +127,12 @@ class Agents(ModuleBase):
127
127
  >>> # Load specific version
128
128
  >>> agent_v2 = await agents.aget("agent-123", version=2)
129
129
  """
130
- return await Agent.aload(agent_id=agent_id, configuration=self.configuration, version=version)
130
+ return await Agent.aload(
131
+ agent_id=agent_id or self.configuration.agent_id or getenv("XPANDER_AGENT_ID"),
132
+ configuration=self.configuration, version=version
133
+ )
131
134
 
132
- def get(self, agent_id: str, version: Optional[int] = None) -> Agent:
135
+ def get(self, agent_id: Optional[str] = None, version: Optional[int] = None) -> Agent:
133
136
  """
134
137
  Synchronously retrieve a specific agent by ID.
135
138
 
@@ -137,7 +140,7 @@ class Agents(ModuleBase):
137
140
  asynchronous method and waits for completion.
138
141
 
139
142
  Args:
140
- agent_id (str): Unique identifier of the agent to retrieve.
143
+ agent_id (Optional[str]): Unique identifier of the agent to retrieve, Fallback to XPANDER_AGENT_ID.
141
144
  version (Optional[int]): Specific version number to load. If None,
142
145
  loads the latest version.
143
146
 
@@ -153,4 +156,9 @@ class Agents(ModuleBase):
153
156
  >>> agent = agents.get("agent-123")
154
157
  >>> result = agent.execute("What is the weather today?")
155
158
  """
156
- return run_sync(self.aget(agent_id=agent_id, version=version))
159
+ return run_sync(
160
+ self.aget(
161
+ agent_id=agent_id,
162
+ version=version
163
+ )
164
+ )