xpander-sdk 2.0.225__tar.gz → 2.0.227__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 (113) hide show
  1. {xpander_sdk-2.0.225 → xpander_sdk-2.0.227}/PKG-INFO +1 -1
  2. {xpander_sdk-2.0.225 → xpander_sdk-2.0.227}/setup.py +1 -1
  3. {xpander_sdk-2.0.225 → xpander_sdk-2.0.227}/src/xpander_sdk/modules/agents/sub_modules/agent.py +7 -0
  4. {xpander_sdk-2.0.225 → xpander_sdk-2.0.227}/src/xpander_sdk/modules/backend/frameworks/agno.py +45 -22
  5. {xpander_sdk-2.0.225 → xpander_sdk-2.0.227}/src/xpander_sdk/modules/tasks/sub_modules/task.py +2 -0
  6. {xpander_sdk-2.0.225 → xpander_sdk-2.0.227}/src/xpander_sdk/modules/tasks/tasks_module.py +3 -0
  7. {xpander_sdk-2.0.225 → xpander_sdk-2.0.227}/src/xpander_sdk.egg-info/PKG-INFO +1 -1
  8. {xpander_sdk-2.0.225 → xpander_sdk-2.0.227}/LICENSE +0 -0
  9. {xpander_sdk-2.0.225 → xpander_sdk-2.0.227}/README.md +0 -0
  10. {xpander_sdk-2.0.225 → xpander_sdk-2.0.227}/pyproject.toml +0 -0
  11. {xpander_sdk-2.0.225 → xpander_sdk-2.0.227}/setup.cfg +0 -0
  12. {xpander_sdk-2.0.225 → xpander_sdk-2.0.227}/src/xpander_sdk/__init__.py +0 -0
  13. {xpander_sdk-2.0.225 → xpander_sdk-2.0.227}/src/xpander_sdk/consts/__init__.py +0 -0
  14. {xpander_sdk-2.0.225 → xpander_sdk-2.0.227}/src/xpander_sdk/consts/api_routes.py +0 -0
  15. {xpander_sdk-2.0.225 → xpander_sdk-2.0.227}/src/xpander_sdk/core/__init__.py +0 -0
  16. {xpander_sdk-2.0.225 → xpander_sdk-2.0.227}/src/xpander_sdk/core/module_base.py +0 -0
  17. {xpander_sdk-2.0.225 → xpander_sdk-2.0.227}/src/xpander_sdk/core/state.py +0 -0
  18. {xpander_sdk-2.0.225 → xpander_sdk-2.0.227}/src/xpander_sdk/core/xpander_api_client.py +0 -0
  19. {xpander_sdk-2.0.225 → xpander_sdk-2.0.227}/src/xpander_sdk/exceptions/__init__.py +0 -0
  20. {xpander_sdk-2.0.225 → xpander_sdk-2.0.227}/src/xpander_sdk/exceptions/module_exception.py +0 -0
  21. {xpander_sdk-2.0.225 → xpander_sdk-2.0.227}/src/xpander_sdk/models/__init__.py +0 -0
  22. {xpander_sdk-2.0.225 → xpander_sdk-2.0.227}/src/xpander_sdk/models/activity.py +0 -0
  23. {xpander_sdk-2.0.225 → xpander_sdk-2.0.227}/src/xpander_sdk/models/compactization.py +0 -0
  24. {xpander_sdk-2.0.225 → xpander_sdk-2.0.227}/src/xpander_sdk/models/configuration.py +0 -0
  25. {xpander_sdk-2.0.225 → xpander_sdk-2.0.227}/src/xpander_sdk/models/deep_planning.py +0 -0
  26. {xpander_sdk-2.0.225 → xpander_sdk-2.0.227}/src/xpander_sdk/models/events.py +0 -0
  27. {xpander_sdk-2.0.225 → xpander_sdk-2.0.227}/src/xpander_sdk/models/frameworks.py +0 -0
  28. {xpander_sdk-2.0.225 → xpander_sdk-2.0.227}/src/xpander_sdk/models/generic.py +0 -0
  29. {xpander_sdk-2.0.225 → xpander_sdk-2.0.227}/src/xpander_sdk/models/notifications.py +0 -0
  30. {xpander_sdk-2.0.225 → xpander_sdk-2.0.227}/src/xpander_sdk/models/orchestrations.py +0 -0
  31. {xpander_sdk-2.0.225 → xpander_sdk-2.0.227}/src/xpander_sdk/models/shared.py +0 -0
  32. {xpander_sdk-2.0.225 → xpander_sdk-2.0.227}/src/xpander_sdk/models/user.py +0 -0
  33. {xpander_sdk-2.0.225 → xpander_sdk-2.0.227}/src/xpander_sdk/modules/__init__.py +0 -0
  34. {xpander_sdk-2.0.225 → xpander_sdk-2.0.227}/src/xpander_sdk/modules/agents/__init__.py +0 -0
  35. {xpander_sdk-2.0.225 → xpander_sdk-2.0.227}/src/xpander_sdk/modules/agents/agents_module.py +0 -0
  36. {xpander_sdk-2.0.225 → xpander_sdk-2.0.227}/src/xpander_sdk/modules/agents/models/__init__.py +0 -0
  37. {xpander_sdk-2.0.225 → xpander_sdk-2.0.227}/src/xpander_sdk/modules/agents/models/agent.py +0 -0
  38. {xpander_sdk-2.0.225 → xpander_sdk-2.0.227}/src/xpander_sdk/modules/agents/models/agent_list.py +0 -0
  39. {xpander_sdk-2.0.225 → xpander_sdk-2.0.227}/src/xpander_sdk/modules/agents/models/knowledge_bases.py +0 -0
  40. {xpander_sdk-2.0.225 → xpander_sdk-2.0.227}/src/xpander_sdk/modules/agents/sub_modules/__init__.py +0 -0
  41. {xpander_sdk-2.0.225 → xpander_sdk-2.0.227}/src/xpander_sdk/modules/agents/utils/__init__.py +0 -0
  42. {xpander_sdk-2.0.225 → xpander_sdk-2.0.227}/src/xpander_sdk/modules/agents/utils/generic.py +0 -0
  43. {xpander_sdk-2.0.225 → xpander_sdk-2.0.227}/src/xpander_sdk/modules/backend/__init__.py +0 -0
  44. {xpander_sdk-2.0.225 → xpander_sdk-2.0.227}/src/xpander_sdk/modules/backend/backend_module.py +0 -0
  45. {xpander_sdk-2.0.225 → xpander_sdk-2.0.227}/src/xpander_sdk/modules/backend/decorators/__init__.py +0 -0
  46. {xpander_sdk-2.0.225 → xpander_sdk-2.0.227}/src/xpander_sdk/modules/backend/decorators/on_auth_event.py +0 -0
  47. {xpander_sdk-2.0.225 → xpander_sdk-2.0.227}/src/xpander_sdk/modules/backend/events_registry.py +0 -0
  48. {xpander_sdk-2.0.225 → xpander_sdk-2.0.227}/src/xpander_sdk/modules/backend/frameworks/__init__.py +0 -0
  49. {xpander_sdk-2.0.225 → xpander_sdk-2.0.227}/src/xpander_sdk/modules/backend/frameworks/dispatch.py +0 -0
  50. {xpander_sdk-2.0.225 → xpander_sdk-2.0.227}/src/xpander_sdk/modules/backend/utils/__init__.py +0 -0
  51. {xpander_sdk-2.0.225 → xpander_sdk-2.0.227}/src/xpander_sdk/modules/backend/utils/mcp_oauth.py +0 -0
  52. {xpander_sdk-2.0.225 → xpander_sdk-2.0.227}/src/xpander_sdk/modules/events/__init__.py +0 -0
  53. {xpander_sdk-2.0.225 → xpander_sdk-2.0.227}/src/xpander_sdk/modules/events/decorators/__init__.py +0 -0
  54. {xpander_sdk-2.0.225 → xpander_sdk-2.0.227}/src/xpander_sdk/modules/events/decorators/on_boot.py +0 -0
  55. {xpander_sdk-2.0.225 → xpander_sdk-2.0.227}/src/xpander_sdk/modules/events/decorators/on_shutdown.py +0 -0
  56. {xpander_sdk-2.0.225 → xpander_sdk-2.0.227}/src/xpander_sdk/modules/events/decorators/on_task.py +0 -0
  57. {xpander_sdk-2.0.225 → xpander_sdk-2.0.227}/src/xpander_sdk/modules/events/decorators/on_tool.py +0 -0
  58. {xpander_sdk-2.0.225 → xpander_sdk-2.0.227}/src/xpander_sdk/modules/events/events_module.py +0 -0
  59. {xpander_sdk-2.0.225 → xpander_sdk-2.0.227}/src/xpander_sdk/modules/events/models/__init__.py +0 -0
  60. {xpander_sdk-2.0.225 → xpander_sdk-2.0.227}/src/xpander_sdk/modules/events/models/deployments.py +0 -0
  61. {xpander_sdk-2.0.225 → xpander_sdk-2.0.227}/src/xpander_sdk/modules/events/models/events.py +0 -0
  62. {xpander_sdk-2.0.225 → xpander_sdk-2.0.227}/src/xpander_sdk/modules/events/utils/__init__.py +0 -0
  63. {xpander_sdk-2.0.225 → xpander_sdk-2.0.227}/src/xpander_sdk/modules/events/utils/generic.py +0 -0
  64. {xpander_sdk-2.0.225 → xpander_sdk-2.0.227}/src/xpander_sdk/modules/events/utils/git_init.py +0 -0
  65. {xpander_sdk-2.0.225 → xpander_sdk-2.0.227}/src/xpander_sdk/modules/knowledge_bases/__init__.py +0 -0
  66. {xpander_sdk-2.0.225 → xpander_sdk-2.0.227}/src/xpander_sdk/modules/knowledge_bases/knowledge_bases_module.py +0 -0
  67. {xpander_sdk-2.0.225 → xpander_sdk-2.0.227}/src/xpander_sdk/modules/knowledge_bases/models/__init__.py +0 -0
  68. {xpander_sdk-2.0.225 → xpander_sdk-2.0.227}/src/xpander_sdk/modules/knowledge_bases/models/knowledge_bases.py +0 -0
  69. {xpander_sdk-2.0.225 → xpander_sdk-2.0.227}/src/xpander_sdk/modules/knowledge_bases/sub_modules/__init__.py +0 -0
  70. {xpander_sdk-2.0.225 → xpander_sdk-2.0.227}/src/xpander_sdk/modules/knowledge_bases/sub_modules/knowledge_base.py +0 -0
  71. {xpander_sdk-2.0.225 → xpander_sdk-2.0.227}/src/xpander_sdk/modules/knowledge_bases/sub_modules/knowledge_base_document_item.py +0 -0
  72. {xpander_sdk-2.0.225 → xpander_sdk-2.0.227}/src/xpander_sdk/modules/knowledge_bases/utils/__init__.py +0 -0
  73. {xpander_sdk-2.0.225 → xpander_sdk-2.0.227}/src/xpander_sdk/modules/tasks/__init__.py +0 -0
  74. {xpander_sdk-2.0.225 → xpander_sdk-2.0.227}/src/xpander_sdk/modules/tasks/models/__init__.py +0 -0
  75. {xpander_sdk-2.0.225 → xpander_sdk-2.0.227}/src/xpander_sdk/modules/tasks/models/task.py +0 -0
  76. {xpander_sdk-2.0.225 → xpander_sdk-2.0.227}/src/xpander_sdk/modules/tasks/models/tasks_list.py +0 -0
  77. {xpander_sdk-2.0.225 → xpander_sdk-2.0.227}/src/xpander_sdk/modules/tasks/sub_modules/__init__.py +0 -0
  78. {xpander_sdk-2.0.225 → xpander_sdk-2.0.227}/src/xpander_sdk/modules/tasks/utils/__init__.py +0 -0
  79. {xpander_sdk-2.0.225 → xpander_sdk-2.0.227}/src/xpander_sdk/modules/tasks/utils/files.py +0 -0
  80. {xpander_sdk-2.0.225 → xpander_sdk-2.0.227}/src/xpander_sdk/modules/tools_repository/__init__.py +0 -0
  81. {xpander_sdk-2.0.225 → xpander_sdk-2.0.227}/src/xpander_sdk/modules/tools_repository/decorators/__init__.py +0 -0
  82. {xpander_sdk-2.0.225 → xpander_sdk-2.0.227}/src/xpander_sdk/modules/tools_repository/decorators/register_tool.py +0 -0
  83. {xpander_sdk-2.0.225 → xpander_sdk-2.0.227}/src/xpander_sdk/modules/tools_repository/models/__init__.py +0 -0
  84. {xpander_sdk-2.0.225 → xpander_sdk-2.0.227}/src/xpander_sdk/modules/tools_repository/models/mcp.py +0 -0
  85. {xpander_sdk-2.0.225 → xpander_sdk-2.0.227}/src/xpander_sdk/modules/tools_repository/models/tool_invocation_result.py +0 -0
  86. {xpander_sdk-2.0.225 → xpander_sdk-2.0.227}/src/xpander_sdk/modules/tools_repository/sub_modules/__init__.py +0 -0
  87. {xpander_sdk-2.0.225 → xpander_sdk-2.0.227}/src/xpander_sdk/modules/tools_repository/sub_modules/tool.py +0 -0
  88. {xpander_sdk-2.0.225 → xpander_sdk-2.0.227}/src/xpander_sdk/modules/tools_repository/tools_repository_module.py +0 -0
  89. {xpander_sdk-2.0.225 → xpander_sdk-2.0.227}/src/xpander_sdk/modules/tools_repository/utils/__init__.py +0 -0
  90. {xpander_sdk-2.0.225 → xpander_sdk-2.0.227}/src/xpander_sdk/modules/tools_repository/utils/generic.py +0 -0
  91. {xpander_sdk-2.0.225 → xpander_sdk-2.0.227}/src/xpander_sdk/modules/tools_repository/utils/local_tools.py +0 -0
  92. {xpander_sdk-2.0.225 → xpander_sdk-2.0.227}/src/xpander_sdk/modules/tools_repository/utils/schemas.py +0 -0
  93. {xpander_sdk-2.0.225 → xpander_sdk-2.0.227}/src/xpander_sdk/utils/__init__.py +0 -0
  94. {xpander_sdk-2.0.225 → xpander_sdk-2.0.227}/src/xpander_sdk/utils/agents/__init__.py +0 -0
  95. {xpander_sdk-2.0.225 → xpander_sdk-2.0.227}/src/xpander_sdk/utils/agents/compactization_agent.py +0 -0
  96. {xpander_sdk-2.0.225 → xpander_sdk-2.0.227}/src/xpander_sdk/utils/env.py +0 -0
  97. {xpander_sdk-2.0.225 → xpander_sdk-2.0.227}/src/xpander_sdk/utils/event_loop.py +0 -0
  98. {xpander_sdk-2.0.225 → xpander_sdk-2.0.227}/src/xpander_sdk/utils/generic.py +0 -0
  99. {xpander_sdk-2.0.225 → xpander_sdk-2.0.227}/src/xpander_sdk/utils/tools.py +0 -0
  100. {xpander_sdk-2.0.225 → xpander_sdk-2.0.227}/src/xpander_sdk.egg-info/SOURCES.txt +0 -0
  101. {xpander_sdk-2.0.225 → xpander_sdk-2.0.227}/src/xpander_sdk.egg-info/dependency_links.txt +0 -0
  102. {xpander_sdk-2.0.225 → xpander_sdk-2.0.227}/src/xpander_sdk.egg-info/requires.txt +0 -0
  103. {xpander_sdk-2.0.225 → xpander_sdk-2.0.227}/src/xpander_sdk.egg-info/top_level.txt +0 -0
  104. {xpander_sdk-2.0.225 → xpander_sdk-2.0.227}/tests/test_agents_module.py +0 -0
  105. {xpander_sdk-2.0.225 → xpander_sdk-2.0.227}/tests/test_api_client.py +0 -0
  106. {xpander_sdk-2.0.225 → xpander_sdk-2.0.227}/tests/test_backend_module.py +0 -0
  107. {xpander_sdk-2.0.225 → xpander_sdk-2.0.227}/tests/test_boot_shutdown_handlers.py +0 -0
  108. {xpander_sdk-2.0.225 → xpander_sdk-2.0.227}/tests/test_configuration.py +0 -0
  109. {xpander_sdk-2.0.225 → xpander_sdk-2.0.227}/tests/test_final_validation.py +0 -0
  110. {xpander_sdk-2.0.225 → xpander_sdk-2.0.227}/tests/test_knowledge_bases_module.py +0 -0
  111. {xpander_sdk-2.0.225 → xpander_sdk-2.0.227}/tests/test_tasks_module.py +0 -0
  112. {xpander_sdk-2.0.225 → xpander_sdk-2.0.227}/tests/test_tool_schema_enhancements.py +0 -0
  113. {xpander_sdk-2.0.225 → xpander_sdk-2.0.227}/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.225
3
+ Version: 2.0.227
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
@@ -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.225",
8
+ version="2.0.227",
9
9
  author="xpanderAI",
10
10
  author_email="dev@xpander.ai",
11
11
  description="xpander.ai Backend-as-a-service for AI Agents - SDK",
@@ -175,6 +175,8 @@ class Agent(XPanderSharedModel):
175
175
  use_oidc_pre_auth: Optional[bool] = False
176
176
  pre_auth_audiences: Optional[List[str]] = []
177
177
  use_oidc_pre_auth_token_for_llm: Optional[bool] = False
178
+ oidc_pre_auth_token_mcp_audience: Optional[bool] = False
179
+ oidc_pre_auth_token_llm_audience: Optional[str] = None
178
180
 
179
181
  Example:
180
182
  >>> agent = Agent(id="agent123", name="Example Agent")
@@ -226,6 +228,8 @@ class Agent(XPanderSharedModel):
226
228
  use_oidc_pre_auth: Optional[bool] = False
227
229
  pre_auth_audiences: Optional[List[str]] = []
228
230
  use_oidc_pre_auth_token_for_llm: Optional[bool] = False
231
+ oidc_pre_auth_token_llm_audience: Optional[str] = None
232
+ oidc_pre_auth_token_mcp_audience: Optional[str] = None
229
233
 
230
234
  _connection_string: Optional[DatabaseConnectionString] = None
231
235
 
@@ -421,6 +425,7 @@ class Agent(XPanderSharedModel):
421
425
  additional_context: Optional[str] = None,
422
426
  instructions_override: Optional[str] = None,
423
427
  test_run_node_id: Optional[str] = None,
428
+ user_oidc_token: Optional[str] = None,
424
429
  expected_output: Optional[str] = None,
425
430
  mcp_servers: Optional[List[MCPServerDetails]] = [],
426
431
  triggering_agent_id: Optional[str] = None,
@@ -448,6 +453,7 @@ class Agent(XPanderSharedModel):
448
453
  additional_context (Optional[str]): Additional context to be passed to the agent.
449
454
  instructions_override (Optional[str]): Additional instructions to be appended to the agent's system prompt.
450
455
  test_run_node_id (Optional[str]): Internal test purpose workflow node id to execute.
456
+ user_oidc_token (Optional[str]): OIDC Token to be used for pre-auth.
451
457
  expected_output (Optional[str]): Expected output of the execution.
452
458
  mcp_servers (Optional[List[MCPServerDetails]]): Optional list of mcp servers to use.
453
459
  triggering_agent_id (Optional[str]): Optional triggering agent id.
@@ -485,6 +491,7 @@ class Agent(XPanderSharedModel):
485
491
  "additional_context": additional_context,
486
492
  "instructions_override": instructions_override,
487
493
  "test_run_node_id": test_run_node_id,
494
+ "user_oidc_token": user_oidc_token,
488
495
  "expected_output": expected_output,
489
496
  "mcp_servers": [server.model_dump() for server in mcp_servers],
490
497
  "triggering_agent_id": triggering_agent_id,
@@ -43,7 +43,7 @@ async def build_agent_args(
43
43
  is_async: Optional[bool] = True,
44
44
  auth_events_callback: Optional[Callable] = None,
45
45
  ) -> Dict[str, Any]:
46
- model = _load_llm_model(agent=xpander_agent, override=override)
46
+ model = _load_llm_model(agent=xpander_agent, override=override, task=task)
47
47
  args: Dict[str, Any] = {
48
48
  "id": xpander_agent.id,
49
49
  "store_events": True
@@ -576,7 +576,7 @@ def _configure_deep_planning_guidance(args: Dict[str, Any], agent: Agent, task:
576
576
  plan_str = task.deep_planning.model_dump_json() if task.deep_planning and task.deep_planning.enabled and len(task.deep_planning.tasks) != 0 else "No execution plan, please generate"
577
577
  args["additional_context"] += f" \n Current execution plan: {plan_str}"
578
578
 
579
- def _load_llm_model(agent: Agent, override: Optional[Dict[str, Any]] = {}) -> Any:
579
+ def _load_llm_model(agent: Agent, override: Optional[Dict[str, Any]] = {}, task: Optional[Task] = None) -> Any:
580
580
  """
581
581
  Load and configure the appropriate LLM model based on the agent's provider configuration.
582
582
 
@@ -613,6 +613,12 @@ def _load_llm_model(agent: Agent, override: Optional[Dict[str, Any]] = {}) -> An
613
613
  has_custom_llm_key = (
614
614
  True if agent.llm_credentials and agent.llm_credentials.value else False
615
615
  )
616
+
617
+ oidc_llm_token = None
618
+
619
+ # OIDC pre-auth token claim by audience
620
+ if agent and agent.pre_auth_audiences and agent.use_oidc_pre_auth_token_for_llm and agent.oidc_pre_auth_token_llm_audience and task and task.user_tokens and isinstance(task.user_tokens, dict) and "oidc_tokens" in task.user_tokens and isinstance(task.user_tokens["oidc_tokens"], dict):
621
+ oidc_llm_token = task.user_tokens["oidc_tokens"].get(agent.oidc_pre_auth_token_llm_audience, None)
616
622
 
617
623
  def get_llm_key(env_var_name: str) -> Optional[str]:
618
624
  """
@@ -624,6 +630,11 @@ def _load_llm_model(agent: Agent, override: Optional[Dict[str, Any]] = {}) -> An
624
630
  Returns:
625
631
  Optional[str]: The resolved API key or None if not available.
626
632
  """
633
+
634
+ # return oidc claimed api key
635
+ if oidc_llm_token:
636
+ return oidc_llm_token
637
+
627
638
  env_llm_key = getenv(env_var_name)
628
639
 
629
640
  # If no custom key available, use environment variable
@@ -641,6 +652,9 @@ def _load_llm_model(agent: Agent, override: Optional[Dict[str, Any]] = {}) -> An
641
652
 
642
653
  llm_extra_headers = {}
643
654
 
655
+ if oidc_llm_token:
656
+ llm_extra_headers["x-oidc-token"] = oidc_llm_token
657
+
644
658
  # Get organization default LLM extra headers
645
659
  api_client = APIClient(configuration=agent.configuration)
646
660
  org_default_llm_headers = run_sync(
@@ -975,27 +989,35 @@ async def _resolve_agent_tools(agent: Agent, task: Optional[Task] = None, auth_e
975
989
  else StreamableHTTPClientParams
976
990
  )
977
991
 
978
- # handle mcp auth
979
- if mcp.auth_type == MCPServerAuthType.OAuth2:
980
- if not task:
981
- raise ValueError("MCP server with OAuth authentication detected but task not sent")
982
-
983
- # check if we have user tokens for this mcp
984
- graph_item = next((gi for gi in agent.graph.items if gi.type == AgentGraphItemType.MCP and gi.settings and gi.settings.mcp_settings and gi.settings.mcp_settings.url and gi.settings.mcp_settings.url == mcp.url), None)
985
- if graph_item and task.user_tokens and isinstance(task.user_tokens, dict) and graph_item.id in task.user_tokens:
986
- mcp.api_key = task.user_tokens[graph_item.id]
987
- else:
988
- if not task.input.user or not task.input.user.id:
989
- raise ValueError("MCP server with OAuth authentication detected but user id not set on the task (task.input.user.id)")
992
+ oidc_mcp_token = None
993
+ # OIDC pre-auth token claim by audience
994
+ if agent and agent.pre_auth_audiences and agent.oidc_pre_auth_token_mcp_audience and task and task.user_tokens and isinstance(task.user_tokens, dict) and "oidc_tokens" in task.user_tokens and isinstance(task.user_tokens["oidc_tokens"], dict):
995
+ oidc_mcp_token = task.user_tokens["oidc_tokens"].get(agent.oidc_pre_auth_token_mcp_audience, None)
996
+ if oidc_mcp_token and oidc_mcp_token != "__none__":
997
+ mcp.api_key = oidc_mcp_token
998
+
999
+ if not oidc_mcp_token:
1000
+ # handle mcp auth
1001
+ if mcp.auth_type == MCPServerAuthType.OAuth2:
1002
+ if not task:
1003
+ raise ValueError("MCP server with OAuth authentication detected but task not sent")
990
1004
 
991
- auth_result: MCPOAuthGetTokenResponse = await authenticate_mcp_server(mcp_server=mcp,task=task,user_id=task.input.user.id, auth_events_callback=auth_events_callback)
992
- if auth_result and auth_result.data and isinstance(auth_result.data, MCPOAuthGetTokenGenericResponse) and auth_result.data.message:
993
- raise ValueError(f"MCP authentication failed: {auth_result.data.message}")
994
- if not auth_result:
995
- raise ValueError("MCP Server authentication failed")
996
- if auth_result.type != MCPOAuthResponseType.TOKEN_READY:
997
- raise ValueError("MCP Server authentication timeout")
998
- mcp.api_key = auth_result.data.access_token
1005
+ # check if we have user tokens for this mcp
1006
+ graph_item = next((gi for gi in agent.graph.items if gi.type == AgentGraphItemType.MCP and gi.settings and gi.settings.mcp_settings and gi.settings.mcp_settings.url and gi.settings.mcp_settings.url == mcp.url), None)
1007
+ if graph_item and task.user_tokens and isinstance(task.user_tokens, dict) and graph_item.id in task.user_tokens:
1008
+ mcp.api_key = task.user_tokens[graph_item.id]
1009
+ else:
1010
+ if not task.input.user or not task.input.user.id:
1011
+ raise ValueError("MCP server with OAuth authentication detected but user id not set on the task (task.input.user.id)")
1012
+
1013
+ auth_result: MCPOAuthGetTokenResponse = await authenticate_mcp_server(mcp_server=mcp,task=task,user_id=task.input.user.id, auth_events_callback=auth_events_callback)
1014
+ if auth_result and auth_result.data and isinstance(auth_result.data, MCPOAuthGetTokenGenericResponse) and auth_result.data.message:
1015
+ raise ValueError(f"MCP authentication failed: {auth_result.data.message}")
1016
+ if not auth_result:
1017
+ raise ValueError("MCP Server authentication failed")
1018
+ if auth_result.type != MCPOAuthResponseType.TOKEN_READY:
1019
+ raise ValueError("MCP Server authentication timeout")
1020
+ mcp.api_key = auth_result.data.access_token
999
1021
 
1000
1022
  if mcp.api_key:
1001
1023
 
@@ -1007,6 +1029,7 @@ async def _resolve_agent_tools(agent: Agent, task: Optional[Task] = None, auth_e
1007
1029
  if not mcp.headers:
1008
1030
  mcp.headers = {}
1009
1031
  mcp.headers["Authorization"] = f"Bearer {mcp.api_key}"
1032
+
1010
1033
  mcp_tools.append(
1011
1034
  MCPTools(
1012
1035
  transport=transport,
@@ -134,6 +134,7 @@ class Task(XPanderSharedModel):
134
134
  additional_context (Optional[str]): Additional context to be passed to the agent.
135
135
  instructions_override (Optional[str]): Additional instructions to be appended to the agent's system prompt.
136
136
  test_run_node_id (Optional[str]): Internal test purpose workflow node id to execute.
137
+ user_oidc_token (Optional[str]): OIDC Token to be used for pre-auth
137
138
  expected_output (Optional[str]): Expected output of the execution.
138
139
  mcp_servers (Optional[List[MCPServerDetails]]): Optional list of mcp servers to use.
139
140
  triggering_agent_id (Optional[str]): Optional triggering agent id.
@@ -184,6 +185,7 @@ class Task(XPanderSharedModel):
184
185
  additional_context: Optional[str] = None
185
186
  instructions_override: Optional[str] = None
186
187
  test_run_node_id: Optional[str] = None
188
+ user_oidc_token: Optional[str] = None
187
189
  expected_output: Optional[str] = (None,)
188
190
  mcp_servers: Optional[List[MCPServerDetails]] = ([],)
189
191
  triggering_agent_id: Optional[str] = (None,)
@@ -236,6 +236,7 @@ class Tasks(ModuleBase):
236
236
  additional_context: Optional[str] = None,
237
237
  instructions_override: Optional[str] = None,
238
238
  test_run_node_id: Optional[str] = None,
239
+ user_oidc_token: Optional[str] = None,
239
240
  expected_output: Optional[str] = None,
240
241
  mcp_servers: Optional[List[MCPServerDetails]] = [],
241
242
  triggering_agent_id: Optional[str] = None,
@@ -267,6 +268,7 @@ class Tasks(ModuleBase):
267
268
  additional_context (Optional[str]): Additional context to be passed to the agent.
268
269
  instructions_override (Optional[str]): Additional instructions to be appended to the agent's system prompt.
269
270
  test_run_node_id (Optional[str]): Internal test purpose workflow node id to execute.
271
+ user_oidc_token (Optional[str]): OIDC Token to be used for pre-auth
270
272
  expected_output (Optional[str]): Expected output of the execution.
271
273
  mcp_servers (Optional[List[MCPServerDetails]]): Optional list of mcp servers to use.
272
274
  triggering_agent_id (Optional[str]): Optional triggering agent id.
@@ -315,6 +317,7 @@ class Tasks(ModuleBase):
315
317
  "additional_context": additional_context,
316
318
  "instructions_override": instructions_override,
317
319
  "test_run_node_id": test_run_node_id,
320
+ "user_oidc_token": user_oidc_token,
318
321
  "expected_output": expected_output,
319
322
  "mcp_servers": [server.model_dump() for server in mcp_servers],
320
323
  "triggering_agent_id": triggering_agent_id,
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: xpander-sdk
3
- Version: 2.0.225
3
+ Version: 2.0.227
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
File without changes
File without changes
File without changes