glaip-sdk 0.6.5b6__py3-none-any.whl → 0.6.6__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.
@@ -1,158 +0,0 @@
1
- """LangChain MCP adapter for local agent runtime.
2
-
3
- This module handles adaptation of glaip-sdk MCP references to aip-agents
4
- MCP configuration format for local execution.
5
-
6
- Authors:
7
- Christian Trisno Sen Long Chen (christian.t.s.l.chen@gdplabs.id)
8
- """
9
-
10
- from typing import Any
11
-
12
- from gllm_core.utils import LoggerManager
13
-
14
- from glaip_sdk.runner.mcp_adapter.base_mcp_adapter import BaseMCPAdapter
15
- from glaip_sdk.runner.mcp_adapter.mcp_config_builder import MCPConfigBuilder
16
-
17
- logger = LoggerManager().get_logger(__name__)
18
-
19
-
20
- class LangChainMCPAdapter(BaseMCPAdapter):
21
- """Adapts glaip-sdk MCPs to aip-agents mcp_config dict format.
22
-
23
- Handles:
24
- - MCP class with http transport → convert to mcp_config
25
- - MCP class with sse transport → convert to mcp_config
26
- - MCP class with stdio transport → convert to mcp_config
27
-
28
- Rejects:
29
- - MCP.from_native() → platform-specific
30
- - String MCP references → platform-specific
31
- """
32
-
33
- def adapt_mcps(self, mcp_refs: list[Any]) -> dict[str, Any]:
34
- """Adapt MCP references to aip-agents mcp_config format.
35
-
36
- Args:
37
- mcp_refs: List of MCP references from Agent definition.
38
-
39
- Returns:
40
- Dictionary mapping server names to configuration dicts.
41
- Format: {server_name: {transport: ..., url: ..., ...}}
42
-
43
- Raises:
44
- ValueError: If MCP is not supported in local mode.
45
- """
46
- mcp_configs = {}
47
-
48
- for mcp_ref in mcp_refs:
49
- server_name, config = self._adapt_single_mcp(mcp_ref)
50
- mcp_configs[server_name] = config
51
-
52
- logger.debug("Adapted %d MCPs to aip-agents format", len(mcp_configs))
53
- return mcp_configs
54
-
55
- def _adapt_single_mcp(self, mcp_ref: Any) -> tuple[str, dict[str, Any]]:
56
- """Adapt a single MCP reference.
57
-
58
- Args:
59
- mcp_ref: Single MCP reference to adapt.
60
-
61
- Returns:
62
- Tuple of (server_name, config_dict).
63
-
64
- Raises:
65
- ValueError: If MCP is not supported.
66
- """
67
- # 1. String references (not supported)
68
- if isinstance(mcp_ref, str):
69
- raise ValueError(self._get_platform_mcp_error(mcp_ref))
70
-
71
- # 2. MCP instance - check if it's local or platform
72
- if self._is_local_mcp(mcp_ref):
73
- config = self._convert_mcp_config(mcp_ref)
74
- return mcp_ref.name, config
75
-
76
- # 3. Platform MCP (from_native, from_id)
77
- if self._is_platform_mcp(mcp_ref):
78
- raise ValueError(self._get_platform_mcp_error(mcp_ref))
79
-
80
- # 4. Unknown type
81
- raise ValueError(
82
- f"Unsupported MCP type for local mode: {type(mcp_ref)}. "
83
- "Local mode only supports MCP class instances with http/sse/stdio transport."
84
- )
85
-
86
- def _is_local_mcp(self, ref: Any) -> bool:
87
- """Check if ref is a local MCP (has transport config)."""
88
- return (
89
- hasattr(ref, "transport")
90
- and hasattr(ref, "name")
91
- and getattr(ref, "transport", None) in ("http", "sse", "stdio")
92
- and not self._is_lookup_only(ref)
93
- )
94
-
95
- def _is_lookup_only(self, ref: Any) -> bool:
96
- """Check if MCP is lookup-only (platform reference)."""
97
- return hasattr(ref, "_lookup_only") and getattr(ref, "_lookup_only", False)
98
-
99
- def _convert_mcp_config(self, mcp: Any) -> dict[str, Any]:
100
- """Convert glaip-sdk MCP to aip-agents mcp_config format.
101
-
102
- Args:
103
- mcp: glaip-sdk MCP instance.
104
-
105
- Returns:
106
- aip-agents compatible MCP config dict.
107
- """
108
- # Start with user-provided config
109
- config = mcp.config.copy() if mcp.config else {}
110
-
111
- # Ensure transport is set
112
- config["transport"] = mcp.transport
113
-
114
- # Map server_url to url if needed (aip-agents uses 'url')
115
- if "server_url" in config and "url" not in config:
116
- config["url"] = config.pop("server_url")
117
-
118
- # Convert authentication to headers using MCPConfigBuilder
119
- if hasattr(mcp, "authentication") and mcp.authentication:
120
- headers = MCPConfigBuilder.build_headers_from_auth(mcp.authentication)
121
- if headers:
122
- config["headers"] = headers
123
- else:
124
- logger.warning("Failed to build headers from authentication for MCP '%s'", mcp.name)
125
-
126
- logger.debug("Converted MCP '%s' with transport '%s'", mcp.name, mcp.transport)
127
- return config
128
-
129
- def _is_platform_mcp(self, ref: Any) -> bool:
130
- """Check if ref is platform-specific (not supported locally)."""
131
- # MCP.from_native() or MCP.from_id() instances
132
- if self._is_lookup_only(ref):
133
- return True
134
-
135
- # MCP with ID but no local transport
136
- if hasattr(ref, "id") and getattr(ref, "id") and not self._is_local_mcp(ref):
137
- return True
138
-
139
- return False
140
-
141
- def _get_platform_mcp_error(self, ref: Any) -> str:
142
- """Get error message for platform MCPs."""
143
- if isinstance(ref, str):
144
- mcp_name = ref
145
- else:
146
- mcp_name = getattr(ref, "name", "<unknown>")
147
-
148
- return (
149
- f"MCP '{mcp_name}' is not supported in local mode.\n\n"
150
- "Local mode only supports MCPs with local transport configurations:\n"
151
- " - MCP(name='...', transport='http', config={{'url': '...'}})\n"
152
- " - MCP(name='...', transport='sse', config={{'url': '...'}})\n"
153
- " - MCP(name='...', transport='stdio', config={{'command': '...'}})\n\n"
154
- "Alternatives:\n"
155
- " 1. Configure MCP with a local server URL\n"
156
- " 2. Deploy the agent to use platform MCPs: agent.deploy()\n"
157
- " 3. Remove MCP for local testing"
158
- )
@@ -1,95 +0,0 @@
1
- """MCP configuration builder helper.
2
-
3
- This module provides utilities for building MCP configurations,
4
- particularly for handling authentication conversion to headers.
5
-
6
- Authors:
7
- Christian Trisno Sen Long Chen (christian.t.s.l.chen@gdplabs.id)
8
- """
9
-
10
- from typing import Any
11
-
12
- from gllm_core.utils import LoggerManager
13
-
14
- logger = LoggerManager().get_logger(__name__)
15
-
16
-
17
- class MCPConfigBuilder:
18
- """Helper class for building MCP configurations.
19
-
20
- Handles authentication-to-headers conversion and configuration validation.
21
- Simplified version focused on local MCP support needs.
22
- """
23
-
24
- @staticmethod
25
- def build_headers_from_auth(authentication: dict[str, Any]) -> dict[str, str] | None:
26
- """Build HTTP headers from authentication configuration.
27
-
28
- Args:
29
- authentication: Authentication configuration dict with 'type' and auth-specific fields.
30
-
31
- Returns:
32
- dict[str, str] | None: HTTP headers or None if invalid/no-auth.
33
- """
34
- if not authentication or "type" not in authentication:
35
- return None
36
-
37
- auth_type = str(authentication["type"]).lower()
38
-
39
- # Dispatch to type-specific handlers
40
- handlers = {
41
- "no-auth": MCPConfigBuilder._handle_no_auth,
42
- "custom-header": MCPConfigBuilder._handle_custom_header,
43
- "bearer-token": MCPConfigBuilder._handle_bearer_token,
44
- "api-key": MCPConfigBuilder._handle_api_key,
45
- }
46
-
47
- handler = handlers.get(auth_type)
48
- if handler:
49
- return handler(authentication)
50
-
51
- logger.warning("Unsupported authentication type: %s", auth_type)
52
- return None
53
-
54
- @staticmethod
55
- def _handle_no_auth(authentication: dict[str, Any]) -> None: # noqa: ARG004
56
- """Handle no-auth type."""
57
- return None
58
-
59
- @staticmethod
60
- def _handle_custom_header(authentication: dict[str, Any]) -> dict[str, str] | None:
61
- """Handle custom-header auth type."""
62
- headers = authentication.get("headers")
63
- if isinstance(headers, dict) and all(isinstance(k, str) and isinstance(v, str) for k, v in headers.items()):
64
- return headers
65
- logger.warning("custom-header auth requires 'headers' dict with string keys/values")
66
- return None
67
-
68
- @staticmethod
69
- def _handle_bearer_token(authentication: dict[str, Any]) -> dict[str, str] | None:
70
- """Handle bearer-token auth type."""
71
- # Check if headers provided directly
72
- headers = authentication.get("headers")
73
- if isinstance(headers, dict):
74
- return headers
75
- # Otherwise build from token
76
- token = authentication.get("token")
77
- if token:
78
- return {"Authorization": f"Bearer {token}"}
79
- logger.warning("bearer-token auth requires 'token' field or 'headers' dict")
80
- return None
81
-
82
- @staticmethod
83
- def _handle_api_key(authentication: dict[str, Any]) -> dict[str, str] | None:
84
- """Handle api-key auth type."""
85
- # Check if headers provided directly
86
- headers = authentication.get("headers")
87
- if isinstance(headers, dict):
88
- return headers
89
- # Otherwise build from key/value
90
- key = authentication.get("key")
91
- value = authentication.get("value")
92
- if key and value:
93
- return {str(key): str(value)}
94
- logger.warning("api-key auth requires 'key' and 'value' fields or 'headers' dict")
95
- return None
@@ -1,18 +0,0 @@
1
- """Tool adapter for local agent runtime.
2
-
3
- This package provides adapters to convert glaip-sdk tool references
4
- to backend-specific formats for local execution.
5
-
6
- Authors:
7
- Christian Trisno Sen Long Chen (christian.t.s.l.chen@gdplabs.id)
8
- """
9
-
10
- from glaip_sdk.runner.tool_adapter.base_tool_adapter import BaseToolAdapter
11
- from glaip_sdk.runner.tool_adapter.langchain_tool_adapter import (
12
- LangChainToolAdapter,
13
- )
14
-
15
- __all__ = [
16
- "BaseToolAdapter",
17
- "LangChainToolAdapter",
18
- ]
@@ -1,44 +0,0 @@
1
- """Base tool adapter for local agent runtime.
2
-
3
- This module defines the abstract base class for tool adapters.
4
- Different backends (LangGraph, Google ADK) implement their own adapters.
5
-
6
- Authors:
7
- Christian Trisno Sen Long Chen (christian.t.s.l.chen@gdplabs.id)
8
- """
9
-
10
- from __future__ import annotations
11
-
12
- from abc import ABC, abstractmethod
13
- from typing import Any
14
-
15
-
16
- class BaseToolAdapter(ABC):
17
- """Abstract base class for tool adapters.
18
-
19
- One Interface, Multiple Implementations:
20
- - LangChainToolAdapter: Adapts to LangChain BaseTool (for aip-agents)
21
- - GoogleADKToolAdapter: Adapts to Google ADK format (future)
22
-
23
- Each backend implements this interface to adapt glaip-sdk tools
24
- to their specific tool format.
25
- """
26
-
27
- @abstractmethod
28
- def adapt_tools(self, tool_refs: list[Any]) -> list[Any]:
29
- """Adapt glaip-sdk tool references to backend-specific format.
30
-
31
- Args:
32
- tool_refs: List of tool references from Agent definition.
33
- Can be: LangChain classes/instances, Tool.from_langchain(),
34
- Tool.from_native(), string names, etc.
35
-
36
- Returns:
37
- List of tools in backend-specific format.
38
- For LangChain: list of BaseTool instances.
39
- For Google ADK: list of Google ADK tool objects.
40
-
41
- Raises:
42
- ValueError: If tool is not supported by this backend.
43
- """
44
- ...
@@ -1,177 +0,0 @@
1
- """LangChain tool adapter for local agent runtime.
2
-
3
- This module handles adaptation of glaip-sdk tool references to LangChain
4
- BaseTool instances for local execution with aip-agents (LangGraph backend).
5
-
6
- Authors:
7
- Christian Trisno Sen Long Chen (christian.t.s.l.chen@gdplabs.id)
8
- """
9
-
10
- from typing import Any
11
-
12
- from gllm_core.utils import LoggerManager
13
-
14
- from glaip_sdk.runner.tool_adapter.base_tool_adapter import BaseToolAdapter
15
-
16
- logger = LoggerManager().get_logger(__name__)
17
-
18
-
19
- class LangChainToolAdapter(BaseToolAdapter):
20
- """Adapts glaip-sdk tools to LangChain BaseTool format for aip-agents.
21
-
22
- Handles:
23
- - LangChain BaseTool classes → instantiate
24
- - LangChain BaseTool instances → return as-is
25
- - Tool.from_langchain() → extract underlying tool
26
- - @tool_plugin decorator → ignore (just metadata)
27
-
28
- Rejects:
29
- - Tool.from_native() → platform-specific
30
- - String tool names → platform-specific
31
- """
32
-
33
- def adapt_tools(self, tool_refs: list[Any]) -> list[Any]:
34
- """Adapt tool references to LangChain BaseTool instances.
35
-
36
- Args:
37
- tool_refs: List of tool references from Agent definition.
38
-
39
- Returns:
40
- List of LangChain BaseTool instances.
41
-
42
- Raises:
43
- ValueError: If tool is not supported in local mode.
44
- """
45
- langchain_tools = []
46
-
47
- for tool_ref in tool_refs:
48
- langchain_tool = self._adapt_single_tool(tool_ref)
49
- langchain_tools.append(langchain_tool)
50
-
51
- logger.debug("Adapted %d tools to LangChain format", len(langchain_tools))
52
- return langchain_tools
53
-
54
- def _adapt_single_tool(self, tool_ref: Any) -> Any:
55
- """Adapt a single tool reference.
56
-
57
- Args:
58
- tool_ref: Single tool reference to adapt.
59
-
60
- Returns:
61
- LangChain BaseTool instance.
62
-
63
- Raises:
64
- ValueError: If tool is not supported.
65
- """
66
- # 1. Tool.from_langchain() wrapper
67
- if self._is_tool_wrapper(tool_ref):
68
- return self._extract_from_wrapper(tool_ref)
69
-
70
- # 2. Direct LangChain BaseTool
71
- if self._is_langchain_tool(tool_ref):
72
- return self._instantiate_langchain_tool(tool_ref)
73
-
74
- # 3. Platform tools (not supported)
75
- if self._is_platform_tool(tool_ref):
76
- raise ValueError(self._get_platform_tool_error(tool_ref))
77
-
78
- # 4. Unknown type
79
- raise ValueError(
80
- f"Unsupported tool type for local mode: {type(tool_ref)}. "
81
- "Local mode only supports LangChain BaseTool classes/instances."
82
- )
83
-
84
- def _is_tool_wrapper(self, ref: Any) -> bool:
85
- """Check if ref is a Tool.from_langchain() wrapper.
86
-
87
- Args:
88
- ref: Object to check.
89
-
90
- Returns:
91
- True if ref is a Tool.from_langchain() wrapper.
92
- """
93
- return hasattr(ref, "langchain_tool") and hasattr(ref, "id") and hasattr(ref, "name")
94
-
95
- def _extract_from_wrapper(self, wrapper: Any) -> Any:
96
- """Extract underlying LangChain tool from Tool.from_langchain().
97
-
98
- Args:
99
- wrapper: Tool.from_langchain() wrapper object.
100
-
101
- Returns:
102
- LangChain BaseTool instance.
103
- """
104
- langchain_tool = wrapper.langchain_tool
105
-
106
- # If it's a class, instantiate it
107
- if isinstance(langchain_tool, type):
108
- langchain_tool = langchain_tool()
109
-
110
- logger.debug(
111
- "Extracted LangChain tool from wrapper: %s",
112
- getattr(langchain_tool, "name", "<unknown>"),
113
- )
114
- return langchain_tool
115
-
116
- def _is_langchain_tool(self, ref: Any) -> bool:
117
- """Check if ref is a LangChain BaseTool class or instance.
118
-
119
- Args:
120
- ref: Object to check.
121
-
122
- Returns:
123
- True if ref is a LangChain BaseTool.
124
- """
125
- from glaip_sdk.utils.tool_detection import is_langchain_tool # noqa: PLC0415
126
-
127
- return is_langchain_tool(ref)
128
-
129
- def _instantiate_langchain_tool(self, ref: Any) -> Any:
130
- """Instantiate LangChain tool if class, return as-is if instance.
131
-
132
- Args:
133
- ref: LangChain BaseTool class or instance.
134
-
135
- Returns:
136
- LangChain BaseTool instance.
137
- """
138
- if isinstance(ref, type):
139
- # It's a class, instantiate it
140
- # Note: @tool_plugin decorator doesn't affect instantiation
141
- return ref()
142
- return ref
143
-
144
- def _is_platform_tool(self, ref: Any) -> bool:
145
- """Check if ref is platform-specific (not supported locally).
146
-
147
- Args:
148
- ref: Object to check.
149
-
150
- Returns:
151
- True if ref is a platform-specific tool.
152
- """
153
- # String tool names
154
- if isinstance(ref, str):
155
- return True
156
-
157
- # Tool.from_native() instances
158
- if hasattr(ref, "id") and hasattr(ref, "name") and not hasattr(ref, "langchain_tool"):
159
- return True
160
-
161
- return False
162
-
163
- def _get_platform_tool_error(self, ref: Any) -> str:
164
- """Get error message for platform tools.
165
-
166
- Args:
167
- ref: Platform tool reference.
168
-
169
- Returns:
170
- Error message string.
171
- """
172
- from glaip_sdk.runner.deps import ( # noqa: PLC0415
173
- get_local_mode_not_supported_for_tool_message,
174
- )
175
-
176
- tool_name = ref if isinstance(ref, str) else getattr(ref, "name", "<unknown>")
177
- return get_local_mode_not_supported_for_tool_message(tool_name)
@@ -1,34 +0,0 @@
1
- """A2A (Agent-to-Agent) event processing utilities.
2
-
3
- This module provides utilities for processing A2A stream events emitted by
4
- agent execution backends. Used by the runner module and CLI rendering.
5
-
6
- Authors:
7
- Christian Trisno Sen Long Chen (christian.t.s.l.chen@gdplabs.id)
8
- """
9
-
10
- from glaip_sdk.utils.a2a.event_processor import (
11
- EVENT_TYPE_ERROR,
12
- EVENT_TYPE_FINAL_RESPONSE,
13
- EVENT_TYPE_STATUS_UPDATE,
14
- EVENT_TYPE_TOOL_CALL,
15
- EVENT_TYPE_TOOL_RESULT,
16
- A2AEventStreamProcessor,
17
- extract_final_response,
18
- get_event_type,
19
- is_error_event,
20
- is_tool_event,
21
- )
22
-
23
- __all__ = [
24
- "A2AEventStreamProcessor",
25
- "EVENT_TYPE_ERROR",
26
- "EVENT_TYPE_FINAL_RESPONSE",
27
- "EVENT_TYPE_STATUS_UPDATE",
28
- "EVENT_TYPE_TOOL_CALL",
29
- "EVENT_TYPE_TOOL_RESULT",
30
- "extract_final_response",
31
- "get_event_type",
32
- "is_error_event",
33
- "is_tool_event",
34
- ]