alita-sdk 0.3.441__py3-none-any.whl → 0.3.443__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.

Potentially problematic release.


This version of alita-sdk might be problematic. Click here for more details.

@@ -342,6 +342,9 @@ class AlitaClient:
342
342
  app_type = "react"
343
343
  elif app_type == 'autogen':
344
344
  app_type = "react"
345
+
346
+ # LangChainAssistant constructor calls get_tools() which may raise McpAuthorizationRequired
347
+ # The exception will propagate naturally to the indexer worker's outer handler
345
348
  if runtime == 'nonrunnable':
346
349
  return LangChainAssistant(self, data, llm, chat_history, app_type,
347
350
  tools=tools, memory=memory, store=store, mcp_tokens=mcp_tokens)
@@ -605,6 +608,9 @@ class AlitaClient:
605
608
  'tools': tools, # Tool configs that will be processed by get_tools()
606
609
  'variables': variables
607
610
  }
611
+
612
+ # LangChainAssistant constructor calls get_tools() which may raise McpAuthorizationRequired
613
+ # The exception will propagate naturally to the indexer worker's outer handler
608
614
  return LangChainAssistant(
609
615
  self,
610
616
  agent_data,
@@ -22,6 +22,7 @@ from ..utils.mcp_oauth import (
22
22
  canonical_resource,
23
23
  extract_resource_metadata_url,
24
24
  fetch_resource_metadata,
25
+ infer_authorization_servers_from_realm,
25
26
  )
26
27
 
27
28
  logger = logging.getLogger(__name__)
@@ -545,8 +546,19 @@ class McpToolkit(BaseToolkit):
545
546
 
546
547
  auth_header = response.headers.get('WWW-Authenticate', '')
547
548
  if response.status_code == 401:
548
- resource_metadata_url = extract_resource_metadata_url(auth_header)
549
+ resource_metadata_url = extract_resource_metadata_url(auth_header, connection_config.url)
549
550
  metadata = fetch_resource_metadata(resource_metadata_url, timeout=timeout) if resource_metadata_url else None
551
+
552
+ # If we couldn't get metadata from the resource_metadata endpoint,
553
+ # infer authorization servers from the WWW-Authenticate header and server URL
554
+ if not metadata or not metadata.get('authorization_servers'):
555
+ inferred_servers = infer_authorization_servers_from_realm(auth_header, connection_config.url)
556
+ if inferred_servers:
557
+ if not metadata:
558
+ metadata = {}
559
+ metadata['authorization_servers'] = inferred_servers
560
+ logger.info(f"Inferred authorization servers for {connection_config.url}: {inferred_servers}")
561
+
550
562
  raise McpAuthorizationRequired(
551
563
  message=f"MCP server {connection_config.url} requires OAuth authorization",
552
564
  server_url=canonical_resource(connection_config.url),
@@ -554,6 +566,7 @@ class McpToolkit(BaseToolkit):
554
566
  www_authenticate=auth_header,
555
567
  resource_metadata=metadata,
556
568
  status=response.status_code,
569
+ tool_name=toolkit_name,
557
570
  )
558
571
 
559
572
  if response.status_code != 200:
@@ -18,6 +18,7 @@ from ..utils.mcp_oauth import (
18
18
  canonical_resource,
19
19
  extract_resource_metadata_url,
20
20
  fetch_resource_metadata_async,
21
+ infer_authorization_servers_from_realm,
21
22
  )
22
23
 
23
24
  logger = logging.getLogger(__name__)
@@ -121,7 +122,7 @@ class McpRemoteTool(McpServerTool):
121
122
  async with session.post(self.server_url, json=mcp_request, headers=headers) as response:
122
123
  auth_header = response.headers.get('WWW-Authenticate') or response.headers.get('Www-Authenticate')
123
124
  if response.status == 401:
124
- resource_metadata_url = extract_resource_metadata_url(auth_header)
125
+ resource_metadata_url = extract_resource_metadata_url(auth_header, self.server_url)
125
126
  metadata = None
126
127
  if resource_metadata_url:
127
128
  metadata = await fetch_resource_metadata_async(
@@ -129,6 +130,17 @@ class McpRemoteTool(McpServerTool):
129
130
  session=session,
130
131
  timeout=self.tool_timeout_sec,
131
132
  )
133
+
134
+ # If we couldn't get metadata from the resource_metadata endpoint,
135
+ # infer authorization servers from the WWW-Authenticate header and server URL
136
+ if not metadata or not metadata.get('authorization_servers'):
137
+ inferred_servers = infer_authorization_servers_from_realm(auth_header, self.server_url)
138
+ if inferred_servers:
139
+ if not metadata:
140
+ metadata = {}
141
+ metadata['authorization_servers'] = inferred_servers
142
+ logger.info(f"Inferred authorization servers for {self.server_url}: {inferred_servers}")
143
+
132
144
  raise McpAuthorizationRequired(
133
145
  message=f"MCP server {self.server_url} requires OAuth authorization",
134
146
  server_url=canonical_resource(self.server_url),
@@ -136,6 +148,7 @@ class McpRemoteTool(McpServerTool):
136
148
  www_authenticate=auth_header,
137
149
  resource_metadata=metadata,
138
150
  status=response.status,
151
+ tool_name=self.name,
139
152
  )
140
153
 
141
154
  if response.status != 200:
@@ -21,6 +21,7 @@ class McpAuthorizationRequired(ToolException):
21
21
  www_authenticate: Optional[str] = None,
22
22
  resource_metadata: Optional[Dict[str, Any]] = None,
23
23
  status: Optional[int] = None,
24
+ tool_name: Optional[str] = None,
24
25
  ):
25
26
  super().__init__(message)
26
27
  self.server_url = server_url
@@ -28,6 +29,7 @@ class McpAuthorizationRequired(ToolException):
28
29
  self.www_authenticate = www_authenticate
29
30
  self.resource_metadata = resource_metadata
30
31
  self.status = status
32
+ self.tool_name = tool_name
31
33
 
32
34
  def to_dict(self) -> Dict[str, Any]:
33
35
  return {
@@ -37,21 +39,65 @@ class McpAuthorizationRequired(ToolException):
37
39
  "www_authenticate": self.www_authenticate,
38
40
  "resource_metadata": self.resource_metadata,
39
41
  "status": self.status,
42
+ "tool_name": self.tool_name,
40
43
  }
41
44
 
42
45
 
43
- def extract_resource_metadata_url(www_authenticate: Optional[str]) -> Optional[str]:
44
- """Pull the resource_metadata URL from a WWW-Authenticate header if present."""
45
- if not www_authenticate:
46
+ def extract_resource_metadata_url(www_authenticate: Optional[str], server_url: Optional[str] = None) -> Optional[str]:
47
+ """
48
+ Pull the resource_metadata URL from a WWW-Authenticate header if present.
49
+ If not found and server_url is provided, try to construct resource metadata URLs.
50
+ """
51
+ if not www_authenticate and not server_url:
46
52
  return None
47
53
 
48
54
  # RFC9728 returns `resource_metadata="<url>"` inside the header value
49
- match = re.search(r'resource_metadata\s*=\s*\"?([^\", ]+)\"?', www_authenticate)
50
- if match:
51
- return match.group(1)
55
+ if www_authenticate:
56
+ match = re.search(r'resource_metadata\s*=\s*\"?([^\", ]+)\"?', www_authenticate)
57
+ if match:
58
+ return match.group(1)
59
+
60
+ # For servers that don't provide resource_metadata in WWW-Authenticate,
61
+ # we'll return None and rely on inferring authorization servers from the realm
62
+ # or using well-known OAuth discovery endpoints directly
52
63
  return None
53
64
 
54
65
 
66
+ def infer_authorization_servers_from_realm(www_authenticate: Optional[str], server_url: str) -> Optional[list]:
67
+ """
68
+ Infer authorization server URLs from WWW-Authenticate realm or server URL.
69
+ This is used when the server doesn't provide resource_metadata endpoint.
70
+ """
71
+ if not www_authenticate and not server_url:
72
+ return None
73
+
74
+ authorization_servers = []
75
+
76
+ # Try to extract realm from WWW-Authenticate header
77
+ realm = None
78
+ if www_authenticate:
79
+ realm_match = re.search(r'realm\s*=\s*\"([^\"]+)\"', www_authenticate)
80
+ if realm_match:
81
+ realm = realm_match.group(1)
82
+
83
+ # Parse the server URL to get base domain
84
+ parsed = urlparse(server_url)
85
+ base_url = f"{parsed.scheme}://{parsed.netloc}"
86
+
87
+ # For OAuth 2.1 / OpenID Connect, try standard well-known endpoints
88
+ # These are the most common discovery endpoints
89
+ if realm and realm.lower() == "oauth":
90
+ # Standard OAuth 2.0 / 2.1 discovery endpoints
91
+ authorization_servers.append(f"{base_url}/.well-known/oauth-authorization-server")
92
+ authorization_servers.append(f"{base_url}/.well-known/openid-configuration")
93
+ else:
94
+ # If no realm or different realm, still try standard endpoints
95
+ authorization_servers.append(f"{base_url}/.well-known/oauth-authorization-server")
96
+ authorization_servers.append(f"{base_url}/.well-known/openid-configuration")
97
+
98
+ return authorization_servers if authorization_servers else None
99
+
100
+
55
101
  def fetch_resource_metadata(resource_metadata_url: str, timeout: int = 10) -> Optional[Dict[str, Any]]:
56
102
  """Fetch and parse the protected resource metadata document."""
57
103
  try:
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: alita_sdk
3
- Version: 0.3.441
3
+ Version: 0.3.443
4
4
  Summary: SDK for building langchain agents using resources from Alita
5
5
  Author-email: Artem Rozumenko <artyom.rozumenko@gmail.com>, Mikalai Biazruchka <mikalai_biazruchka@epam.com>, Roman Mitusov <roman_mitusov@epam.com>, Ivan Krakhmaliuk <lifedj27@gmail.com>, Artem Dubrovskiy <ad13box@gmail.com>
6
6
  License-Expression: Apache-2.0
@@ -36,7 +36,7 @@ alita_sdk/configurations/zephyr_essential.py,sha256=TiZedsBlfIDroflipvoqxjJeEWPo
36
36
  alita_sdk/runtime/__init__.py,sha256=4W0UF-nl3QF2bvET5lnah4o24CoTwSoKXhuN0YnwvEE,828
37
37
  alita_sdk/runtime/clients/__init__.py,sha256=BdehU5GBztN1Qi1Wul0cqlU46FxUfMnI6Vq2Zd_oq1M,296
38
38
  alita_sdk/runtime/clients/artifact.py,sha256=b7hVuGRROt6qUcT11uAZqzJqslzmlgW-Y6oGsiwNmjI,4029
39
- alita_sdk/runtime/clients/client.py,sha256=3GAbPSBq4P2Tgkn4kQK4zHfjzkHxKvzcsLWM-i3-JoM,47362
39
+ alita_sdk/runtime/clients/client.py,sha256=trgvD6vzOqepn29ks0i1ALKigdVxiBinaJiOi-ejNb0,47754
40
40
  alita_sdk/runtime/clients/datasource.py,sha256=HAZovoQN9jBg0_-lIlGBQzb4FJdczPhkHehAiVG3Wx0,1020
41
41
  alita_sdk/runtime/clients/mcp_discovery.py,sha256=aFJ0wYQ8EAmXa9qLUusHZfQXkNec1wbgkqHdVeSFX-g,11697
42
42
  alita_sdk/runtime/clients/mcp_manager.py,sha256=DRbqiO761l7UgOdv_keHbD2g0oZodtPHejpArXYZIoE,9050
@@ -103,7 +103,7 @@ alita_sdk/runtime/toolkits/application.py,sha256=HHAKgwKOckxc7EQG-AV7rz4POOzQJKF
103
103
  alita_sdk/runtime/toolkits/artifact.py,sha256=YChNCX4QhVpaQG7Jk4TS-Wl0Aruc4slQ2K21zh9nNO0,3176
104
104
  alita_sdk/runtime/toolkits/configurations.py,sha256=kIDAlnryPQfbZyFxV-9SzN2-Vefzx06TX1BBdIIpN90,141
105
105
  alita_sdk/runtime/toolkits/datasource.py,sha256=qk78OdPoReYPCWwahfkKLbKc4pfsu-061oXRryFLP6I,2498
106
- alita_sdk/runtime/toolkits/mcp.py,sha256=9avAcSn94BZxjM0W8l-qw0jqydV9N8p_3Hyqfr8uFmM,38963
106
+ alita_sdk/runtime/toolkits/mcp.py,sha256=rzwEwW4LR-8aqVPsW-QvUSC0qMVM2MyOn0uH_m7VQjo,39797
107
107
  alita_sdk/runtime/toolkits/prompt.py,sha256=WIpTkkVYWqIqOWR_LlSWz3ug8uO9tm5jJ7aZYdiGRn0,1192
108
108
  alita_sdk/runtime/toolkits/subgraph.py,sha256=wwUK8JjPXkGzyVZ3tAukmvST6eGbqx_U11rpnmbrvtg,2105
109
109
  alita_sdk/runtime/toolkits/tools.py,sha256=F93TOPQWmULpslyJh-lCEdkQ3OD4RbEvfe84g8wBzb0,11639
@@ -122,7 +122,7 @@ alita_sdk/runtime/tools/llm.py,sha256=iRG_wU4T01LRsjEMPZe5Uah7LiMqDc-vspwkMuQtlt
122
122
  alita_sdk/runtime/tools/loop.py,sha256=uds0WhZvwMxDVFI6MZHrcmMle637cQfBNg682iLxoJA,8335
123
123
  alita_sdk/runtime/tools/loop_output.py,sha256=U4hO9PCQgWlXwOq6jdmCGbegtAxGAPXObSxZQ3z38uk,8069
124
124
  alita_sdk/runtime/tools/mcp_inspect_tool.py,sha256=38X8euaxDbEGjcfp6ElvExZalpZun6QEr6ZEW4nU5pQ,11496
125
- alita_sdk/runtime/tools/mcp_remote_tool.py,sha256=7iZS2r5xgiRRYk5PySdGC2FQ55ZvVfIqH7dCvPiL_hY,9487
125
+ alita_sdk/runtime/tools/mcp_remote_tool.py,sha256=odt6j54SjeP0vaVo0cZkV2GHoZtPSTRh6owtVcqFytk,10396
126
126
  alita_sdk/runtime/tools/mcp_server_tool.py,sha256=-xO3H6BM63KaIV1CdcQKPVE0WPigiqOgFZDX7m2_yGs,4419
127
127
  alita_sdk/runtime/tools/pgvector_search.py,sha256=NN2BGAnq4SsDHIhUcFZ8d_dbEOM8QwB0UwpsWCYruXU,11692
128
128
  alita_sdk/runtime/tools/prompt.py,sha256=nJafb_e5aOM1Rr3qGFCR-SKziU9uCsiP2okIMs9PppM,741
@@ -136,7 +136,7 @@ alita_sdk/runtime/utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG
136
136
  alita_sdk/runtime/utils/constants.py,sha256=Xntx1b_uxUzT4clwqHA_U6K8y5bBqf_4lSQwXdcWrp4,13586
137
137
  alita_sdk/runtime/utils/evaluate.py,sha256=iM1P8gzBLHTuSCe85_Ng_h30m52hFuGuhNXJ7kB1tgI,1872
138
138
  alita_sdk/runtime/utils/logging.py,sha256=svPyiW8ztDfhqHFITv5FBCj8UhLxz6hWcqGIY6wpJJE,3331
139
- alita_sdk/runtime/utils/mcp_oauth.py,sha256=fh4jM0UjV65-MGNno7o-7_kpRd6pY57fgZ63Cl-v46E,3791
139
+ alita_sdk/runtime/utils/mcp_oauth.py,sha256=icGG2j3mzKS2ARVmq0r_MPhHBiHrXMJ0DtIcU7y7TLQ,5826
140
140
  alita_sdk/runtime/utils/save_dataframe.py,sha256=i-E1wp-t4wb17Zq3nA3xYwgSILjoXNizaQAA9opWvxY,1576
141
141
  alita_sdk/runtime/utils/streamlit.py,sha256=yIb4YIGH8HRAXZtZlywjxI07Xdcb5eUt7rMA-elFTdc,107261
142
142
  alita_sdk/runtime/utils/toolkit_runtime.py,sha256=MU63Fpxj0b5_r1IUUc0Q3-PN9VwL7rUxp2MRR4tmYR8,5136
@@ -360,8 +360,8 @@ alita_sdk/tools/zephyr_scale/api_wrapper.py,sha256=kT0TbmMvuKhDUZc0i7KO18O38JM9S
360
360
  alita_sdk/tools/zephyr_squad/__init__.py,sha256=0ne8XLJEQSLOWfzd2HdnqOYmQlUliKHbBED5kW_Vias,2895
361
361
  alita_sdk/tools/zephyr_squad/api_wrapper.py,sha256=kmw_xol8YIYFplBLWTqP_VKPRhL_1ItDD0_vXTe_UuI,14906
362
362
  alita_sdk/tools/zephyr_squad/zephyr_squad_cloud_client.py,sha256=R371waHsms4sllHCbijKYs90C-9Yu0sSR3N4SUfQOgU,5066
363
- alita_sdk-0.3.441.dist-info/licenses/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
364
- alita_sdk-0.3.441.dist-info/METADATA,sha256=C0gyyRq4qwLPvIy-IjF6z7JR6JnXcmRtRlUKYKH0FfY,19071
365
- alita_sdk-0.3.441.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
366
- alita_sdk-0.3.441.dist-info/top_level.txt,sha256=0vJYy5p_jK6AwVb1aqXr7Kgqgk3WDtQ6t5C-XI9zkmg,10
367
- alita_sdk-0.3.441.dist-info/RECORD,,
363
+ alita_sdk-0.3.443.dist-info/licenses/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
364
+ alita_sdk-0.3.443.dist-info/METADATA,sha256=cepzPrDlxn1tJo2xZwFUGT-y8nw5lZCT_9gzHVLwWkI,19071
365
+ alita_sdk-0.3.443.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
366
+ alita_sdk-0.3.443.dist-info/top_level.txt,sha256=0vJYy5p_jK6AwVb1aqXr7Kgqgk3WDtQ6t5C-XI9zkmg,10
367
+ alita_sdk-0.3.443.dist-info/RECORD,,