aixtools 0.2.17__tar.gz → 0.2.19__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.

Potentially problematic release.


This version of aixtools might be problematic. Click here for more details.

Files changed (101) hide show
  1. {aixtools-0.2.17 → aixtools-0.2.19}/PKG-INFO +1 -1
  2. {aixtools-0.2.17 → aixtools-0.2.19}/aixtools/_version.py +3 -3
  3. {aixtools-0.2.17 → aixtools-0.2.19}/aixtools/a2a/google_sdk/utils.py +15 -7
  4. {aixtools-0.2.17 → aixtools-0.2.19}/aixtools/agents/agent.py +1 -1
  5. {aixtools-0.2.17 → aixtools-0.2.19}/aixtools/mcp/client.py +44 -41
  6. {aixtools-0.2.17 → aixtools-0.2.19}/aixtools/server/utils.py +36 -2
  7. {aixtools-0.2.17 → aixtools-0.2.19}/README.md +0 -0
  8. {aixtools-0.2.17 → aixtools-0.2.19}/aixtools/.chainlit/config.toml +0 -0
  9. {aixtools-0.2.17 → aixtools-0.2.19}/aixtools/.chainlit/translations/bn.json +0 -0
  10. {aixtools-0.2.17 → aixtools-0.2.19}/aixtools/.chainlit/translations/en-US.json +0 -0
  11. {aixtools-0.2.17 → aixtools-0.2.19}/aixtools/.chainlit/translations/gu.json +0 -0
  12. {aixtools-0.2.17 → aixtools-0.2.19}/aixtools/.chainlit/translations/he-IL.json +0 -0
  13. {aixtools-0.2.17 → aixtools-0.2.19}/aixtools/.chainlit/translations/hi.json +0 -0
  14. {aixtools-0.2.17 → aixtools-0.2.19}/aixtools/.chainlit/translations/ja.json +0 -0
  15. {aixtools-0.2.17 → aixtools-0.2.19}/aixtools/.chainlit/translations/kn.json +0 -0
  16. {aixtools-0.2.17 → aixtools-0.2.19}/aixtools/.chainlit/translations/ml.json +0 -0
  17. {aixtools-0.2.17 → aixtools-0.2.19}/aixtools/.chainlit/translations/mr.json +0 -0
  18. {aixtools-0.2.17 → aixtools-0.2.19}/aixtools/.chainlit/translations/nl.json +0 -0
  19. {aixtools-0.2.17 → aixtools-0.2.19}/aixtools/.chainlit/translations/ta.json +0 -0
  20. {aixtools-0.2.17 → aixtools-0.2.19}/aixtools/.chainlit/translations/te.json +0 -0
  21. {aixtools-0.2.17 → aixtools-0.2.19}/aixtools/.chainlit/translations/zh-CN.json +0 -0
  22. {aixtools-0.2.17 → aixtools-0.2.19}/aixtools/__init__.py +0 -0
  23. {aixtools-0.2.17 → aixtools-0.2.19}/aixtools/a2a/app.py +0 -0
  24. {aixtools-0.2.17 → aixtools-0.2.19}/aixtools/a2a/google_sdk/__init__.py +0 -0
  25. {aixtools-0.2.17 → aixtools-0.2.19}/aixtools/a2a/google_sdk/pydantic_ai_adapter/agent_executor.py +0 -0
  26. {aixtools-0.2.17 → aixtools-0.2.19}/aixtools/a2a/google_sdk/pydantic_ai_adapter/storage.py +0 -0
  27. {aixtools-0.2.17 → aixtools-0.2.19}/aixtools/a2a/google_sdk/remote_agent_connection.py +0 -0
  28. {aixtools-0.2.17 → aixtools-0.2.19}/aixtools/a2a/utils.py +0 -0
  29. {aixtools-0.2.17 → aixtools-0.2.19}/aixtools/agents/__init__.py +0 -0
  30. {aixtools-0.2.17 → aixtools-0.2.19}/aixtools/agents/agent_batch.py +0 -0
  31. {aixtools-0.2.17 → aixtools-0.2.19}/aixtools/agents/nodes_to_md.py +0 -0
  32. {aixtools-0.2.17 → aixtools-0.2.19}/aixtools/agents/nodes_to_message.py +0 -0
  33. {aixtools-0.2.17 → aixtools-0.2.19}/aixtools/agents/nodes_to_str.py +0 -0
  34. {aixtools-0.2.17 → aixtools-0.2.19}/aixtools/agents/print_nodes.py +0 -0
  35. {aixtools-0.2.17 → aixtools-0.2.19}/aixtools/agents/prompt.py +0 -0
  36. {aixtools-0.2.17 → aixtools-0.2.19}/aixtools/app.py +0 -0
  37. {aixtools-0.2.17 → aixtools-0.2.19}/aixtools/auth/__init__.py +0 -0
  38. {aixtools-0.2.17 → aixtools-0.2.19}/aixtools/auth/auth.py +0 -0
  39. {aixtools-0.2.17 → aixtools-0.2.19}/aixtools/chainlit.md +0 -0
  40. {aixtools-0.2.17 → aixtools-0.2.19}/aixtools/compliance/__init__.py +0 -0
  41. {aixtools-0.2.17 → aixtools-0.2.19}/aixtools/compliance/private_data.py +0 -0
  42. {aixtools-0.2.17 → aixtools-0.2.19}/aixtools/context.py +0 -0
  43. {aixtools-0.2.17 → aixtools-0.2.19}/aixtools/db/__init__.py +0 -0
  44. {aixtools-0.2.17 → aixtools-0.2.19}/aixtools/db/database.py +0 -0
  45. {aixtools-0.2.17 → aixtools-0.2.19}/aixtools/db/vector_db.py +0 -0
  46. {aixtools-0.2.17 → aixtools-0.2.19}/aixtools/evals/__init__.py +0 -0
  47. {aixtools-0.2.17 → aixtools-0.2.19}/aixtools/evals/__main__.py +0 -0
  48. {aixtools-0.2.17 → aixtools-0.2.19}/aixtools/evals/dataset.py +0 -0
  49. {aixtools-0.2.17 → aixtools-0.2.19}/aixtools/evals/discovery.py +0 -0
  50. {aixtools-0.2.17 → aixtools-0.2.19}/aixtools/evals/run_evals.py +0 -0
  51. {aixtools-0.2.17 → aixtools-0.2.19}/aixtools/google/client.py +0 -0
  52. {aixtools-0.2.17 → aixtools-0.2.19}/aixtools/log_view/__init__.py +0 -0
  53. {aixtools-0.2.17 → aixtools-0.2.19}/aixtools/log_view/app.py +0 -0
  54. {aixtools-0.2.17 → aixtools-0.2.19}/aixtools/log_view/display.py +0 -0
  55. {aixtools-0.2.17 → aixtools-0.2.19}/aixtools/log_view/export.py +0 -0
  56. {aixtools-0.2.17 → aixtools-0.2.19}/aixtools/log_view/filters.py +0 -0
  57. {aixtools-0.2.17 → aixtools-0.2.19}/aixtools/log_view/log_utils.py +0 -0
  58. {aixtools-0.2.17 → aixtools-0.2.19}/aixtools/log_view/node_summary.py +0 -0
  59. {aixtools-0.2.17 → aixtools-0.2.19}/aixtools/logfilters/__init__.py +0 -0
  60. {aixtools-0.2.17 → aixtools-0.2.19}/aixtools/logfilters/context_filter.py +0 -0
  61. {aixtools-0.2.17 → aixtools-0.2.19}/aixtools/logging/__init__.py +0 -0
  62. {aixtools-0.2.17 → aixtools-0.2.19}/aixtools/logging/log_objects.py +0 -0
  63. {aixtools-0.2.17 → aixtools-0.2.19}/aixtools/logging/logging_config.py +0 -0
  64. {aixtools-0.2.17 → aixtools-0.2.19}/aixtools/logging/mcp_log_models.py +0 -0
  65. {aixtools-0.2.17 → aixtools-0.2.19}/aixtools/logging/mcp_logger.py +0 -0
  66. {aixtools-0.2.17 → aixtools-0.2.19}/aixtools/logging/mcp_middleware.py +0 -0
  67. {aixtools-0.2.17 → aixtools-0.2.19}/aixtools/logging/model_patch_logging.py +0 -0
  68. {aixtools-0.2.17 → aixtools-0.2.19}/aixtools/logging/open_telemetry.py +0 -0
  69. {aixtools-0.2.17 → aixtools-0.2.19}/aixtools/mcp/__init__.py +0 -0
  70. {aixtools-0.2.17 → aixtools-0.2.19}/aixtools/mcp/example_client.py +0 -0
  71. {aixtools-0.2.17 → aixtools-0.2.19}/aixtools/mcp/example_server.py +0 -0
  72. {aixtools-0.2.17 → aixtools-0.2.19}/aixtools/mcp/exceptions.py +0 -0
  73. {aixtools-0.2.17 → aixtools-0.2.19}/aixtools/mcp/fast_mcp_log.py +0 -0
  74. {aixtools-0.2.17 → aixtools-0.2.19}/aixtools/mcp/faulty_mcp.py +0 -0
  75. {aixtools-0.2.17 → aixtools-0.2.19}/aixtools/model_patch/model_patch.py +0 -0
  76. {aixtools-0.2.17 → aixtools-0.2.19}/aixtools/server/__init__.py +0 -0
  77. {aixtools-0.2.17 → aixtools-0.2.19}/aixtools/server/app_mounter.py +0 -0
  78. {aixtools-0.2.17 → aixtools-0.2.19}/aixtools/server/path.py +0 -0
  79. {aixtools-0.2.17 → aixtools-0.2.19}/aixtools/testing/__init__.py +0 -0
  80. {aixtools-0.2.17 → aixtools-0.2.19}/aixtools/testing/agent_mock.py +0 -0
  81. {aixtools-0.2.17 → aixtools-0.2.19}/aixtools/testing/aix_test_model.py +0 -0
  82. {aixtools-0.2.17 → aixtools-0.2.19}/aixtools/testing/mock_tool.py +0 -0
  83. {aixtools-0.2.17 → aixtools-0.2.19}/aixtools/testing/model_patch_cache.py +0 -0
  84. {aixtools-0.2.17 → aixtools-0.2.19}/aixtools/tools/doctor/__init__.py +0 -0
  85. {aixtools-0.2.17 → aixtools-0.2.19}/aixtools/tools/doctor/mcp_tool_doctor.py +0 -0
  86. {aixtools-0.2.17 → aixtools-0.2.19}/aixtools/tools/doctor/tool_doctor.py +0 -0
  87. {aixtools-0.2.17 → aixtools-0.2.19}/aixtools/tools/doctor/tool_recommendation.py +0 -0
  88. {aixtools-0.2.17 → aixtools-0.2.19}/aixtools/utils/__init__.py +0 -0
  89. {aixtools-0.2.17 → aixtools-0.2.19}/aixtools/utils/chainlit/cl_agent_show.py +0 -0
  90. {aixtools-0.2.17 → aixtools-0.2.19}/aixtools/utils/chainlit/cl_utils.py +0 -0
  91. {aixtools-0.2.17 → aixtools-0.2.19}/aixtools/utils/config.py +0 -0
  92. {aixtools-0.2.17 → aixtools-0.2.19}/aixtools/utils/config_util.py +0 -0
  93. {aixtools-0.2.17 → aixtools-0.2.19}/aixtools/utils/enum_with_description.py +0 -0
  94. {aixtools-0.2.17 → aixtools-0.2.19}/aixtools/utils/files.py +0 -0
  95. {aixtools-0.2.17 → aixtools-0.2.19}/aixtools/utils/persisted_dict.py +0 -0
  96. {aixtools-0.2.17 → aixtools-0.2.19}/aixtools/utils/utils.py +0 -0
  97. {aixtools-0.2.17 → aixtools-0.2.19}/aixtools/vault/__init__.py +0 -0
  98. {aixtools-0.2.17 → aixtools-0.2.19}/aixtools/vault/vault.py +0 -0
  99. {aixtools-0.2.17 → aixtools-0.2.19}/aixtools.egg-info/SOURCES.txt +0 -0
  100. {aixtools-0.2.17 → aixtools-0.2.19}/pyproject.toml +0 -0
  101. {aixtools-0.2.17 → aixtools-0.2.19}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: aixtools
3
- Version: 0.2.17
3
+ Version: 0.2.19
4
4
  Summary: Tools for AI exploration and debugging
5
5
  Requires-Python: >=3.11.2
6
6
  Description-Content-Type: text/markdown
@@ -28,7 +28,7 @@ version_tuple: VERSION_TUPLE
28
28
  commit_id: COMMIT_ID
29
29
  __commit_id__: COMMIT_ID
30
30
 
31
- __version__ = version = '0.2.17'
32
- __version_tuple__ = version_tuple = (0, 2, 17)
31
+ __version__ = version = '0.2.19'
32
+ __version_tuple__ = version_tuple = (0, 2, 19)
33
33
 
34
- __commit_id__ = commit_id = 'ga621dde20'
34
+ __commit_id__ = commit_id = 'g09e184e90'
@@ -11,6 +11,7 @@ from a2a.utils import AGENT_CARD_WELL_KNOWN_PATH, PREV_AGENT_CARD_WELL_KNOWN_PAT
11
11
  from aixtools.a2a.google_sdk.remote_agent_connection import RemoteAgentConnection
12
12
  from aixtools.context import DEFAULT_SESSION_ID, DEFAULT_USER_ID, SessionIdTuple
13
13
  from aixtools.logging.logging_config import get_logger
14
+ from aixtools.server.utils import create_session_headers
14
15
 
15
16
  logger = get_logger(__name__)
16
17
 
@@ -23,6 +24,7 @@ class AgentCardLoadFailedError(Exception):
23
24
 
24
25
  async def get_agent_card(client: httpx.AsyncClient, address: str) -> AgentCard:
25
26
  """Retrieve the agent card from the given agent address."""
27
+ warnings = []
26
28
  for card_path in [AGENT_CARD_WELL_KNOWN_PATH, PREV_AGENT_CARD_WELL_KNOWN_PATH]:
27
29
  try:
28
30
  card_resolver = A2ACardResolver(client, address, card_path)
@@ -30,8 +32,10 @@ async def get_agent_card(client: httpx.AsyncClient, address: str) -> AgentCard:
30
32
  card.url = address
31
33
  return card
32
34
  except Exception as e:
33
- logger.warning(f"Error retrieving agent card from {address} at path {card_path}: {e}")
35
+ warnings.append(f"Error retrieving agent card from {address} at path {card_path}: {e}")
34
36
 
37
+ for warning in warnings:
38
+ logger.warning(warning)
35
39
  raise AgentCardLoadFailedError(f"Failed to load agent card from {address}")
36
40
 
37
41
 
@@ -65,15 +69,19 @@ class _AgentCardResolver:
65
69
 
66
70
 
67
71
  async def get_a2a_clients(
68
- ctx: SessionIdTuple, agent_hosts: list[str], *, timeout: float = DEFAULT_A2A_TIMEOUT
72
+ agent_hosts: list[str],
73
+ session_id_tuple: SessionIdTuple,
74
+ auth_token: str = None,
75
+ *,
76
+ timeout: float = DEFAULT_A2A_TIMEOUT,
69
77
  ) -> dict[str, RemoteAgentConnection]:
70
78
  """Get A2A clients for all agents defined in the configuration."""
71
- headers = {
72
- "user-id": ctx[0],
73
- "session-id": ctx[1],
74
- }
79
+ headers = create_session_headers(session_id_tuple, auth_token)
75
80
  httpx_client = httpx.AsyncClient(headers=headers, timeout=timeout, follow_redirects=True)
76
- return await _AgentCardResolver(httpx_client).get_a2a_clients(agent_hosts)
81
+ clients = await _AgentCardResolver(httpx_client).get_a2a_clients(agent_hosts)
82
+ for client in clients.values():
83
+ logger.info("Using A2A server at: %s", client.get_agent_card().url)
84
+ return clients
77
85
 
78
86
 
79
87
  def card2description(card: AgentCard) -> str:
@@ -105,7 +105,7 @@ def get_model(model_family=MODEL_FAMILY, model_name=None, http_client=None, **kw
105
105
  case "azure":
106
106
  return _get_model_openai_azure(model_name=model_name or AZURE_MODEL_NAME, http_client=http_client, **kwargs)
107
107
  case "bedrock":
108
- return _get_model_bedrock(model_name=model_name or BEDROCK_MODEL_NAME, http_client=http_client, **kwargs)
108
+ return _get_model_bedrock(model_name=model_name or BEDROCK_MODEL_NAME, **kwargs)
109
109
  case "ollama":
110
110
  return _get_model_ollama(model_name=model_name or OLLAMA_MODEL_NAME, http_client=http_client, **kwargs)
111
111
  case "openai":
@@ -3,6 +3,7 @@
3
3
  import asyncio
4
4
  import logging
5
5
  from contextlib import asynccontextmanager
6
+ from dataclasses import dataclass, field
6
7
  from datetime import timedelta
7
8
  from typing import Any, AsyncGenerator
8
9
 
@@ -21,6 +22,7 @@ from pydantic_ai.toolsets.abstract import ToolsetTool
21
22
 
22
23
  from aixtools.context import SessionIdTuple
23
24
  from aixtools.logging.logging_config import get_logger
25
+ from aixtools.server.utils import create_session_headers
24
26
 
25
27
  MCP_TOOL_CACHE_TTL = 300 # 5 minutes
26
28
  DEFAULT_MCP_CONNECTION_TIMEOUT = 30
@@ -49,6 +51,14 @@ async def default_mcp_log_handler(message: LogMessage):
49
51
  logger.log(level, msg, extra=extra)
50
52
 
51
53
 
54
+ @dataclass
55
+ class MCPConfig:
56
+ """Configuration for an MCP server retrieved from config.yaml"""
57
+
58
+ url: str
59
+ read_timeout: float = field(default=DEFAULT_MCP_READ_TIMEOUT)
60
+
61
+
52
62
  def get_mcp_client(
53
63
  url: str | None = None,
54
64
  command: str | None = None,
@@ -73,57 +83,50 @@ def get_mcp_client(
73
83
  raise ValueError("Either url or command must be provided to create MCP client.")
74
84
 
75
85
 
76
- def get_mcp_headers(session_id_tuple: SessionIdTuple) -> dict[str, str] | None:
86
+ def get_mcp_servers(
87
+ mcp_configs: list[MCPConfig],
88
+ session_id_tuple: SessionIdTuple,
89
+ auth_token: str = None,
90
+ *,
91
+ timeout: float = DEFAULT_MCP_CONNECTION_TIMEOUT,
92
+ ):
77
93
  """
78
- Generate headers for MCP server requests.
94
+ Create cached MCP server instances with robust error handling and isolation.
79
95
 
80
- This function creates a dictionary of headers to be used in requests to
81
- the MCP servers. If a `user_id` or `session_id` is provided, they are
82
- included in the headers.
96
+ This function creates and returns a list of `CachedMCPServerStreamableHTTP` instances
97
+ based on the provided URLs. Each server instance includes:
98
+ - TTL-based caching for tool lists (5 minutes default)
99
+ - Complete task isolation to prevent cancellation propagation
100
+ - Comprehensive error handling and fallback mechanisms
101
+ - Optional user/session headers for request authentication
83
102
 
84
103
  Args:
85
- session_id_tuple (SessionIdTuple): user_id and session_id tuple
104
+ mcp_configs (list[MCPConfig]): A list of MCP server configurations to use.
105
+ session_id_tuple (SessionIdTuple): A tuple containing (user_id, session_id).
106
+ auth_token (str, optional): The authentication token for the user. Defaults to None.
107
+ timeout (float, optional): Timeout in seconds for MCP server connections.
86
108
  Returns:
87
- dict[str, str] | None: A dictionary of headers for MCP server requests,
88
- or None if neither user_id nor session_id is
89
- provided. When None is returned, default headers
90
- from the client or transport will be used.
109
+ list[CachedMCPServerStreamableHTTP]: List of cached MCP server instances with
110
+ isolation and error handling. Each server
111
+ operates independently - failures in one
112
+ server won't affect others.
91
113
  """
92
- headers = None
93
- user_id, session_id = session_id_tuple
94
- if session_id or user_id:
95
- headers = {}
96
- if session_id:
97
- headers["session-id"] = session_id
98
- if user_id:
99
- headers["user-id"] = user_id
100
- return headers
114
+ headers = create_session_headers(session_id_tuple, auth_token)
115
+ servers = []
116
+ for config in mcp_configs:
117
+ server = CachedMCPServerStreamableHTTP(
118
+ url=config.url, headers=headers, timeout=timeout, read_timeout=config.read_timeout
119
+ )
120
+ logger.info("Using MCP server at %s", config.url)
121
+ servers.append(server)
122
+ return servers
101
123
 
102
124
 
103
125
  def get_configured_mcp_servers(
104
126
  session_id_tuple: SessionIdTuple, mcp_urls: list[str], timeout: int = DEFAULT_MCP_CONNECTION_TIMEOUT
105
127
  ):
106
- """
107
- Retrieve the configured MCP server instances with optional caching.
108
-
109
- Context values `user_id` and `session_id` are included in the headers for each server request.
110
-
111
- Each server is wrapped in a try-except block to isolate them from each other.
112
- If one server fails, it won't affect the others.
113
-
114
- Args:
115
- session_id_tuple (SessionIdTuple): A tuple containing (user_id, session_id).
116
- mcp_urls: (list[str], optional): A list of MCP server URLs to use.
117
- timeout (int, optional): Timeout in seconds for MCP server connections. Defaults to 30 seconds.
118
- Returns:
119
- list[MCPServerStreamableHTTP]: A list of configured MCP server instances. If
120
- neither user_id nor session_id is provided, the
121
- server instances will use default headers defined
122
- by the underlying HTTP implementation.
123
- """
124
- headers = get_mcp_headers(session_id_tuple)
125
-
126
- return [CachedMCPServerStreamableHTTP(url=url, headers=headers, timeout=timeout) for url in mcp_urls]
128
+ """Create MCP server instances from a list of URLs."""
129
+ return get_mcp_servers([MCPConfig(url=url) for url in mcp_urls], session_id_tuple, timeout=timeout)
127
130
 
128
131
 
129
132
  class CachedMCPServerStreamableHTTP(MCPServerStreamableHTTP):
@@ -259,7 +262,7 @@ class CachedMCPServerStreamableHTTP(MCPServerStreamableHTTP):
259
262
 
260
263
  # First, check if we have a valid cached result
261
264
  if CACHE_KEY in self._tools_cache:
262
- logger.info("Using cached tools for %s", self.url)
265
+ logger.debug("Using cached tools for %s", self.url)
263
266
  return self._tools_cache[CACHE_KEY]
264
267
 
265
268
  # Create isolated task to prevent cancellation propagation
@@ -8,10 +8,13 @@ from functools import wraps
8
8
  from fastmcp import Context
9
9
  from fastmcp.server import dependencies
10
10
 
11
- from ..context import DEFAULT_SESSION_ID, DEFAULT_USER_ID, session_id_var, user_id_var
11
+ from ..context import DEFAULT_SESSION_ID, DEFAULT_USER_ID, SessionIdTuple, session_id_var, user_id_var
12
+ from ..logging.logging_config import get_logger
12
13
 
14
+ logger = get_logger(__name__)
13
15
 
14
- def get_session_id_tuple(ctx: Context | None = None) -> tuple[str, str]:
16
+
17
+ def get_session_id_tuple(ctx: Context | None = None) -> SessionIdTuple:
15
18
  """
16
19
  Get the user and session IDs from the user session.
17
20
  If `ctx` is None, the current FastMCP request HTTP headers are used.
@@ -60,6 +63,37 @@ def get_session_id_str(ctx: Context | None = None) -> str:
60
63
  return f"{user_id}:{session_id}"
61
64
 
62
65
 
66
+ def create_session_headers(session_id_tuple: SessionIdTuple, auth_token: str | None = None) -> dict[str, str]:
67
+ """
68
+ Generate headers for MCP or A2A server requests.
69
+
70
+ This function creates a dictionary of headers to be used in requests to
71
+ the MCP servers. If a `user_id` or `session_id` is provided, they are
72
+ included in the headers.
73
+
74
+ Args:
75
+ session_id_tuple (SessionIdTuple): user_id and session_id tuple
76
+ auth_token (str | None): Optional authorization token to include in headers
77
+
78
+ Returns:
79
+ dict[str, str]: A dictionary of headers for MCP server requests.
80
+ May be empty if no user_id, session_id, or auth_token is provided.
81
+ """
82
+ headers = {}
83
+ user_id, session_id = session_id_tuple
84
+ if auth_token:
85
+ logger.debug("Using auth token for MCP server authentication for user:%s, session_id:%s", user_id, session_id)
86
+ headers["Authorization"] = f"Bearer {auth_token}"
87
+ else:
88
+ logger.warning("No auth token found to forward to MCP/A2A servers.")
89
+
90
+ if session_id:
91
+ headers["session-id"] = session_id
92
+ if user_id:
93
+ headers["user-id"] = user_id
94
+ return headers
95
+
96
+
63
97
  def run_in_thread(func):
64
98
  """decorator to run blocking function with `asyncio.to_thread`"""
65
99
 
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes