aip-agents-binary 0.5.20__py3-none-macosx_13_0_arm64.whl → 0.5.22__py3-none-macosx_13_0_arm64.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,4 +1,4 @@
1
- """Minimal LangGraph agent with bosa support example demonstrating asynchronous run.
1
+ """Minimal LangGraph agent with GL Connectors support example demonstrating asynchronous run.
2
2
 
3
3
  Authors:
4
4
  Saul Sayers (saul.sayers@gdplabs.id)
@@ -6,22 +6,24 @@ Authors:
6
6
 
7
7
  import asyncio
8
8
 
9
+ from aip_agents.agent import LangGraphAgent
10
+ from aip_agents.tools import GL_CONNECTORS_AUTOMATED_TOOLS
11
+ from dotenv import load_dotenv
9
12
  from langchain_openai import ChatOpenAI
10
13
 
11
- from aip_agents.agent import LangGraphAgent
12
- from aip_agents.tools import BOSA_AUTOMATED_TOOLS
14
+ load_dotenv(override=True)
13
15
 
14
16
 
15
- async def langgraph_bosa_example():
17
+ async def langgraph_gl_connector_example():
16
18
  """Demonstrates the LangGraphAgent's arun method."""
17
19
  model = ChatOpenAI(model="gpt-4.1", temperature=0)
18
- agent_name = "BOSAConnectorTwitterAgent"
20
+ agent_name = "GLConnectorTwitterAgent"
19
21
 
20
22
  langgraph_agent = LangGraphAgent(
21
23
  name=agent_name,
22
- instruction="You are a helpful assistant that use BOSA connector to connect with Twitter API.",
24
+ instruction="You are a helpful assistant that uses GL Connectors to connect with the Twitter API.",
23
25
  model=model,
24
- tools=BOSA_AUTOMATED_TOOLS["twitter"],
26
+ tools=GL_CONNECTORS_AUTOMATED_TOOLS["twitter"],
25
27
  )
26
28
 
27
29
  query = "Get 3 tweets about the latest Air India Incident"
@@ -38,4 +40,4 @@ async def langgraph_bosa_example():
38
40
 
39
41
 
40
42
  if __name__ == "__main__":
41
- asyncio.run(langgraph_bosa_example())
43
+ asyncio.run(langgraph_gl_connector_example())
@@ -0,0 +1,5 @@
1
+ from aip_agents.agent import LangGraphAgent as LangGraphAgent
2
+ from aip_agents.tools import GL_CONNECTORS_AUTOMATED_TOOLS as GL_CONNECTORS_AUTOMATED_TOOLS
3
+
4
+ async def langgraph_gl_connector_example() -> None:
5
+ """Demonstrates the LangGraphAgent's arun method."""
@@ -1,4 +1,4 @@
1
- """This is a simple FastAPI app to test Sentry with Open Telemetry from BOSA SDK.
1
+ """This is a simple FastAPI app to test Sentry with Open Telemetry from GL Connectors SDK.
2
2
 
3
3
  To run this example, make sure to set the following environment variables:
4
4
  SENTRY_DSN
@@ -20,13 +20,12 @@ import threading
20
20
  import time
21
21
 
22
22
  import uvicorn
23
- from fastapi import FastAPI
24
- from fastapi.responses import JSONResponse
25
- from fastapi.staticfiles import StaticFiles
26
-
27
23
  from aip_agents.examples.hello_world_langgraph import langgraph_example
28
24
  from aip_agents.sentry import setup_telemetry
29
25
  from aip_agents.utils.logger import get_logger
26
+ from fastapi import FastAPI
27
+ from fastapi.responses import JSONResponse
28
+ from fastapi.staticfiles import StaticFiles
30
29
 
31
30
  logger = get_logger(__name__)
32
31
 
@@ -50,7 +49,9 @@ def fetch_endpoints():
50
49
  # Because using request.get() will trigger sentry, but the ep name is not saved.
51
50
  # Instead of GET /langgraph-hello-world, sentry will save it as GET
52
51
  url = f"http://127.0.0.1:8585{ep}"
53
- result = subprocess.run(["curl", "-i", url], capture_output=True, text=True, check=False)
52
+ result = subprocess.run(
53
+ ["curl", "-i", url], capture_output=True, text=True, check=False
54
+ )
54
55
  logger.info(result.stdout)
55
56
  except Exception as e:
56
57
  logger.error(f"Error fetching {ep}: {e}")
@@ -63,7 +64,7 @@ def create_app() -> FastAPI:
63
64
  FastAPI: The configured FastAPI application.
64
65
  """
65
66
  app = FastAPI(
66
- title="Bosa SDK - Sentry with Open Telemetry",
67
+ title="GL Connectors SDK - Sentry with Open Telemetry",
67
68
  description="This is a simple FastAPI app to test Sentry with Open Telemetry.",
68
69
  version="0.0.1",
69
70
  docs_url=None,
@@ -1,4 +1,4 @@
1
- """This module provides a centralized way to handle Sentry and OpenTelemetry configuration for BOSA SDK.
1
+ """This module provides a centralized way to handle Sentry and OpenTelemetry configuration for GL Connectors SDK.
2
2
 
3
3
  Authors:
4
4
  Saul Sayers (saul.sayers@gdplabs.id)
@@ -1,4 +1,4 @@
1
- """This file contains the Sentry and OpenTelemetry configuration for BOSA SDK.
1
+ """This file contains the Sentry and OpenTelemetry configuration for GL Connectors SDK.
2
2
 
3
3
  Authors:
4
4
  Saul Sayers (saul.sayers@gdplabs.id)
@@ -7,6 +7,8 @@ Authors:
7
7
  import inspect
8
8
  import os
9
9
 
10
+ from aip_agents.agent import BaseAgent, GoogleADKAgent, LangChainAgent, LangGraphAgent
11
+ from aip_agents.utils.logger import get_logger
10
12
  from bosa_core.telemetry import (
11
13
  FastAPIConfig,
12
14
  OpenTelemetryConfig,
@@ -20,9 +22,6 @@ from bosa_core.telemetry.opentelemetry.instrument.functions import (
20
22
  from dotenv import load_dotenv
21
23
  from fastapi import FastAPI
22
24
 
23
- from aip_agents.agent import BaseAgent, GoogleADKAgent, LangChainAgent, LangGraphAgent
24
- from aip_agents.utils.logger import get_logger
25
-
26
25
  load_dotenv()
27
26
 
28
27
 
@@ -56,13 +55,17 @@ def get_all_methods(cls: type) -> list:
56
55
  for name, member in inspect.getmembers(cls):
57
56
  if name.startswith("_"):
58
57
  continue # skip dunder and private
59
- if inspect.isfunction(member) or inspect.ismethod(member) or inspect.iscoroutinefunction(member):
58
+ if (
59
+ inspect.isfunction(member)
60
+ or inspect.ismethod(member)
61
+ or inspect.iscoroutinefunction(member)
62
+ ):
60
63
  methods.append(member)
61
64
  return methods
62
65
 
63
66
 
64
- def instrument_bosa_functions() -> None:
65
- """Instrument BOSA functions."""
67
+ def instrument_gl_functions() -> None:
68
+ """Instrument GL functions."""
66
69
  if BOSAFunctionsInstrumentor is None:
67
70
  return
68
71
  agent_methods = []
@@ -111,7 +114,9 @@ def setup_sentry_with_open_telemetry(app: FastAPI) -> None:
111
114
 
112
115
  telemetry_config = TelemetryConfig(sentry_config=sentry_config)
113
116
  init_telemetry(telemetry_config)
114
- logger.info(f"Telemetry initialized with OpenTelemetry for environment: {SENTRY_ENVIRONMENT}")
117
+ logger.info(
118
+ f"Telemetry initialized with OpenTelemetry for environment: {SENTRY_ENVIRONMENT}"
119
+ )
115
120
  except Exception as e:
116
121
  logger.error(f"Failed to initialize telemetry with OpenTelemetry: {e}")
117
122
 
@@ -130,7 +135,9 @@ def setup_sentry_only() -> None:
130
135
 
131
136
  telemetry_config = TelemetryConfig(sentry_config=sentry_config)
132
137
  init_telemetry(telemetry_config)
133
- logger.info(f"Telemetry initialized with Sentry only for environment: {SENTRY_ENVIRONMENT}")
138
+ logger.info(
139
+ f"Telemetry initialized with Sentry only for environment: {SENTRY_ENVIRONMENT}"
140
+ )
134
141
  except Exception as e:
135
142
  logger.error(f"Failed to initialize telemetry with Sentry only: {e}")
136
143
 
@@ -148,4 +155,4 @@ def setup_telemetry(app: FastAPI) -> None:
148
155
  setup_sentry_with_open_telemetry(app)
149
156
  else:
150
157
  setup_sentry_only()
151
- instrument_bosa_functions()
158
+ instrument_gl_functions()
@@ -21,8 +21,8 @@ def get_all_methods(cls) -> list:
21
21
  Returns:
22
22
  list: A list of methods.
23
23
  """
24
- def instrument_bosa_functions() -> None:
25
- """Instrument BOSA functions."""
24
+ def instrument_gl_functions() -> None:
25
+ """Instrument GL functions."""
26
26
  def traces_sampler(*args) -> float:
27
27
  """Determine appropriate sampling rate for Sentry transactions.
28
28
 
@@ -1,13 +1,23 @@
1
1
  """Initialize Tools Module for AIP Agents."""
2
2
 
3
3
  from importlib import import_module
4
+ from typing import TYPE_CHECKING
4
5
 
5
- from aip_agents.tools.bosa_tools import BOSA_AUTOMATED_TOOLS
6
+ from aip_agents.tools.gl_connector_tools import GL_CONNECTORS_AUTOMATED_TOOLS, BOSA_AUTOMATED_TOOLS
6
7
  from aip_agents.tools.gl_connector import GLConnectorTool
7
8
  from aip_agents.tools.time_tool import TimeTool
8
9
  from aip_agents.tools.web_search import GoogleSerperTool
10
+ from aip_agents.utils.logger import get_logger
9
11
 
10
- __all__ = ["BOSA_AUTOMATED_TOOLS", "GLConnectorTool", "GoogleSerperTool", "TimeTool"]
12
+ logger = get_logger(__name__)
13
+
14
+ __all__ = [
15
+ "BOSA_AUTOMATED_TOOLS",
16
+ "GL_CONNECTORS_AUTOMATED_TOOLS",
17
+ "GLConnectorTool",
18
+ "GoogleSerperTool",
19
+ "TimeTool",
20
+ ]
11
21
 
12
22
 
13
23
  def _register_optional(module_path: str, export_name: str) -> None:
@@ -19,11 +29,16 @@ def _register_optional(module_path: str, export_name: str) -> None:
19
29
  """
20
30
  try:
21
31
  module = import_module(module_path)
22
- except ImportError:
23
- return
32
+ tool = getattr(module, export_name)
33
+ __all__.append(export_name)
34
+ globals()[export_name] = tool
24
35
 
25
- globals()[export_name] = getattr(module, export_name)
26
- __all__.append(export_name)
36
+ except ImportError as e:
37
+ logger.debug(f"Module {module_path} not found: {e}")
38
+ except AttributeError as e:
39
+ logger.debug(f"Tool {export_name} not found in module {module_path}: {e}")
40
+ except Exception as e:
41
+ logger.debug(f"Unexpected error loading {export_name}: {e}")
27
42
 
28
43
 
29
44
  _register_optional("aip_agents.tools.browser_use", "BrowserUseTool")
@@ -31,3 +46,8 @@ _register_optional("aip_agents.tools.code_sandbox", "E2BCodeSandboxTool")
31
46
  _register_optional("aip_agents.tools.document_loader", "DocxReaderTool")
32
47
  _register_optional("aip_agents.tools.document_loader", "ExcelReaderTool")
33
48
  _register_optional("aip_agents.tools.document_loader", "PDFReaderTool")
49
+
50
+ if TYPE_CHECKING:
51
+ from aip_agents.tools.browser_use import BrowserUseTool
52
+ from aip_agents.tools.code_sandbox import E2BCodeSandboxTool
53
+ from aip_agents.tools.document_loader import DocxReaderTool, ExcelReaderTool, PDFReaderTool
@@ -1,13 +1,9 @@
1
- from aip_agents.tools.bosa_tools import BOSA_AUTOMATED_TOOLS as BOSA_AUTOMATED_TOOLS
1
+ from aip_agents.tools.browser_use import BrowserUseTool as BrowserUseTool
2
+ from aip_agents.tools.code_sandbox import E2BCodeSandboxTool as E2BCodeSandboxTool
3
+ from aip_agents.tools.document_loader import DocxReaderTool as DocxReaderTool, ExcelReaderTool as ExcelReaderTool, PDFReaderTool as PDFReaderTool
2
4
  from aip_agents.tools.gl_connector import GLConnectorTool as GLConnectorTool
5
+ from aip_agents.tools.gl_connector_tools import BOSA_AUTOMATED_TOOLS as BOSA_AUTOMATED_TOOLS, GL_CONNECTORS_AUTOMATED_TOOLS as GL_CONNECTORS_AUTOMATED_TOOLS
3
6
  from aip_agents.tools.time_tool import TimeTool as TimeTool
4
7
  from aip_agents.tools.web_search import GoogleSerperTool as GoogleSerperTool
5
8
 
6
- __all__ = ['BOSA_AUTOMATED_TOOLS', 'GLConnectorTool', 'GoogleSerperTool', 'TimeTool', 'BrowserUseTool', 'E2BCodeSandboxTool', 'DocxReaderTool', 'ExcelReaderTool', 'PDFReaderTool']
7
-
8
- # Names in __all__ with no definition:
9
- # BrowserUseTool
10
- # DocxReaderTool
11
- # E2BCodeSandboxTool
12
- # ExcelReaderTool
13
- # PDFReaderTool
9
+ __all__ = ['BOSA_AUTOMATED_TOOLS', 'GL_CONNECTORS_AUTOMATED_TOOLS', 'GLConnectorTool', 'GoogleSerperTool', 'TimeTool', 'BrowserUseTool', 'E2BCodeSandboxTool', 'DocxReaderTool', 'ExcelReaderTool', 'PDFReaderTool']
@@ -1,4 +1,4 @@
1
- """Constants for tools using BOSA Connector.
1
+ """Constants for tools using GL Connectors.
2
2
 
3
3
  Authors:
4
4
  Saul Sayers (saul.sayers@gdplabs.id)
@@ -7,20 +7,34 @@ Authors:
7
7
  import os
8
8
  from enum import Enum, StrEnum
9
9
 
10
- BOSA_API_BASE_URL = os.getenv("BOSA_API_BASE_URL")
11
- BOSA_API_KEY = os.getenv("BOSA_API_KEY")
12
- BOSA_FETCH_MAX_RETRIES = 3
10
+ GL_CONNECTORS_BASE_URL = (
11
+ os.getenv("GL_CONNECTORS_BASE_URL")
12
+ or os.getenv("GL_CONNECTORS_API_BASE_URL")
13
+ or os.getenv("BOSA_API_BASE_URL")
14
+ or os.getenv("BOSA_BASE_URL")
15
+ )
16
+ GL_CONNECTORS_API_KEY = os.getenv("GL_CONNECTORS_API_KEY") or os.getenv("BOSA_API_KEY")
17
+ GL_CONNECTORS_FETCH_MAX_RETRIES = int(
18
+ os.getenv("GL_CONNECTORS_FETCH_MAX_RETRIES")
19
+ or os.getenv("BOSA_FETCH_MAX_RETRIES")
20
+ or 3
21
+ )
22
+
23
+ # For backward compatibility
24
+ BOSA_API_BASE_URL = GL_CONNECTORS_BASE_URL
25
+ BOSA_API_KEY = GL_CONNECTORS_API_KEY
26
+ BOSA_FETCH_MAX_RETRIES = GL_CONNECTORS_FETCH_MAX_RETRIES
13
27
 
14
28
 
15
29
  class ToolType(StrEnum):
16
- """Tool types for BOSA Connector."""
30
+ """Tool types for GL Connectors."""
17
31
 
18
32
  GLLM = "gllm"
19
33
  LANGCHAIN = "langchain"
20
34
 
21
35
 
22
36
  class Action(Enum):
23
- """Actions for BOSA Connector."""
37
+ """Actions for GL Connectors."""
24
38
 
25
39
  GITHUB = "github"
26
40
  GOOGLE = "google"
@@ -30,7 +44,7 @@ class Action(Enum):
30
44
 
31
45
 
32
46
  class GitHubEndpoint(Enum):
33
- """GitHub endpoints for BOSA Connector."""
47
+ """GitHub endpoints for GL Connectors."""
34
48
 
35
49
  INTEGRATIONS = "integrations"
36
50
  USER_HAS_INTEGRATION = "integration-exists"
@@ -59,7 +73,7 @@ class GitHubEndpoint(Enum):
59
73
 
60
74
 
61
75
  class GoogleDriveEndpoint(Enum):
62
- """Google Drive endpoints for BOSA Connector."""
76
+ """Google Drive endpoints for GL Connectors."""
63
77
 
64
78
  INTEGRATIONS = "integrations"
65
79
  USER_HAS_INTEGRATION = "integration-exists"
@@ -84,7 +98,7 @@ class GoogleDriveEndpoint(Enum):
84
98
 
85
99
 
86
100
  class GoogleDocsEndpoint(Enum):
87
- """Google Docs endpoints for BOSA Connector."""
101
+ """Google Docs endpoints for GL Connectors."""
88
102
 
89
103
  INTEGRATIONS = "integrations"
90
104
  USER_HAS_INTEGRATION = "integration-exists"
@@ -100,7 +114,7 @@ class GoogleDocsEndpoint(Enum):
100
114
 
101
115
 
102
116
  class GoogleEndpoint(Enum):
103
- """Google endpoints for BOSA Connector."""
117
+ """Google endpoints for GL Connectors."""
104
118
 
105
119
  INTEGRATIONS = "integrations"
106
120
  USER_HAS_INTEGRATION = "integration-exists"
@@ -109,7 +123,7 @@ class GoogleEndpoint(Enum):
109
123
 
110
124
 
111
125
  class TwitterEndpoint(Enum):
112
- """Twitter endpoints for BOSA Connector."""
126
+ """Twitter endpoints for GL Connectors."""
113
127
 
114
128
  INTEGRATIONS = "integrations"
115
129
  USER_HAS_INTEGRATION = "integration-exists"
@@ -121,7 +135,7 @@ class TwitterEndpoint(Enum):
121
135
 
122
136
 
123
137
  class GoogleMailEndpoint(Enum):
124
- """Google Mail endpoints for BOSA Connector."""
138
+ """Google Mail endpoints for GL Connectors."""
125
139
 
126
140
  INTEGRATIONS = "integrations"
127
141
  USER_HAS_INTEGRATION = "integration-exists"
@@ -1,17 +1,20 @@
1
1
  from _typeshed import Incomplete
2
2
  from enum import Enum, StrEnum
3
3
 
4
- BOSA_API_BASE_URL: Incomplete
5
- BOSA_API_KEY: Incomplete
6
- BOSA_FETCH_MAX_RETRIES: int
4
+ GL_CONNECTORS_BASE_URL: Incomplete
5
+ GL_CONNECTORS_API_KEY: Incomplete
6
+ GL_CONNECTORS_FETCH_MAX_RETRIES: Incomplete
7
+ BOSA_API_BASE_URL = GL_CONNECTORS_BASE_URL
8
+ BOSA_API_KEY = GL_CONNECTORS_API_KEY
9
+ BOSA_FETCH_MAX_RETRIES = GL_CONNECTORS_FETCH_MAX_RETRIES
7
10
 
8
11
  class ToolType(StrEnum):
9
- """Tool types for BOSA Connector."""
12
+ """Tool types for GL Connectors."""
10
13
  GLLM: str
11
14
  LANGCHAIN: str
12
15
 
13
16
  class Action(Enum):
14
- """Actions for BOSA Connector."""
17
+ """Actions for GL Connectors."""
15
18
  GITHUB: str
16
19
  GOOGLE: str
17
20
  GOOGLE_DRIVE: str
@@ -19,7 +22,7 @@ class Action(Enum):
19
22
  TWITTER: str
20
23
 
21
24
  class GitHubEndpoint(Enum):
22
- """GitHub endpoints for BOSA Connector."""
25
+ """GitHub endpoints for GL Connectors."""
23
26
  INTEGRATIONS: str
24
27
  USER_HAS_INTEGRATION: str
25
28
  SUCCESS_AUTHORIZE_CALLBACK: str
@@ -46,7 +49,7 @@ class GitHubEndpoint(Enum):
46
49
  LIST_PROJECTS: str
47
50
 
48
51
  class GoogleDriveEndpoint(Enum):
49
- """Google Drive endpoints for BOSA Connector."""
52
+ """Google Drive endpoints for GL Connectors."""
50
53
  INTEGRATIONS: str
51
54
  USER_HAS_INTEGRATION: str
52
55
  SUCCESS_AUTHORIZE_CALLBACK: str
@@ -69,7 +72,7 @@ class GoogleDriveEndpoint(Enum):
69
72
  DOWNLOAD_FILE: str
70
73
 
71
74
  class GoogleDocsEndpoint(Enum):
72
- """Google Docs endpoints for BOSA Connector."""
75
+ """Google Docs endpoints for GL Connectors."""
73
76
  INTEGRATIONS: str
74
77
  USER_HAS_INTEGRATION: str
75
78
  SUCCESS_AUTHORIZE_CALLBACK: str
@@ -83,14 +86,14 @@ class GoogleDocsEndpoint(Enum):
83
86
  SUMMARIZE_COMMENTS: str
84
87
 
85
88
  class GoogleEndpoint(Enum):
86
- """Google endpoints for BOSA Connector."""
89
+ """Google endpoints for GL Connectors."""
87
90
  INTEGRATIONS: str
88
91
  USER_HAS_INTEGRATION: str
89
92
  SUCCESS_AUTHORIZE_CALLBACK: str
90
93
  USERINFO: str
91
94
 
92
95
  class TwitterEndpoint(Enum):
93
- """Twitter endpoints for BOSA Connector."""
96
+ """Twitter endpoints for GL Connectors."""
94
97
  INTEGRATIONS: str
95
98
  USER_HAS_INTEGRATION: str
96
99
  SUCCESS_AUTHORIZE_CALLBACK: str
@@ -100,7 +103,7 @@ class TwitterEndpoint(Enum):
100
103
  GET_USERS: str
101
104
 
102
105
  class GoogleMailEndpoint(Enum):
103
- """Google Mail endpoints for BOSA Connector."""
106
+ """Google Mail endpoints for GL Connectors."""
104
107
  INTEGRATIONS: str
105
108
  USER_HAS_INTEGRATION: str
106
109
  SUCCESS_AUTHORIZE_CALLBACK: str
@@ -1,4 +1,4 @@
1
- """GL Connector tool wrapper exports."""
1
+ """GL Connectors tool wrapper exports."""
2
2
 
3
3
  from aip_agents.tools.gl_connector.tool import GLConnectorTool
4
4
 
@@ -1,7 +1,8 @@
1
- """GL Connector tool wrapper for BOSA connector tools.
1
+ """Wrapper for GL Connectors.
2
2
 
3
3
  Authors:
4
4
  Saul Sayers (saul.sayers@gdplabs.id)
5
+ Christian Trisno Sen Long Chen (christian.t.s.l.chen@gdplabs.id)
5
6
 
6
7
  Reference:
7
8
  https://gl-docs.gitbook.io/bosa/gl-connector/gl-connector
@@ -13,19 +14,30 @@ import os
13
14
  from collections.abc import Iterable
14
15
  from typing import Any
15
16
 
17
+ from aip_agents.tools.constants import ToolType
16
18
  from bosa_connectors import BosaConnector, BOSAConnectorToolGenerator
17
19
  from langchain_core.runnables import RunnableConfig
18
20
  from langchain_core.tools import BaseTool
19
21
  from pydantic import ConfigDict, PrivateAttr
20
22
 
21
- from aip_agents.tools.constants import ToolType
22
-
23
23
  _REQUIRED_ENV_VARS: tuple[str, ...] = (
24
- "BOSA_BASE_URL",
25
- "BOSA_API_KEY",
26
- "BOSA_USERNAME",
27
- "BOSA_PASSWORD",
24
+ "GL_CONNECTORS_BASE_URL",
25
+ "GL_CONNECTORS_API_KEY",
26
+ "GL_CONNECTORS_USERNAME",
27
+ "GL_CONNECTORS_PASSWORD",
28
28
  )
29
+
30
+ _ENV_VAR_MAPPING: dict[str, tuple[str, ...]] = {
31
+ "GL_CONNECTORS_BASE_URL": (
32
+ "GL_CONNECTORS_BASE_URL",
33
+ "BOSA_BASE_URL",
34
+ "BOSA_API_BASE_URL",
35
+ ),
36
+ "GL_CONNECTORS_API_KEY": ("GL_CONNECTORS_API_KEY", "BOSA_API_KEY"),
37
+ "GL_CONNECTORS_USERNAME": ("GL_CONNECTORS_USERNAME", "BOSA_USERNAME"),
38
+ "GL_CONNECTORS_PASSWORD": ("GL_CONNECTORS_PASSWORD", "BOSA_PASSWORD"),
39
+ "GL_CONNECTORS_IDENTIFIER": ("GL_CONNECTORS_IDENTIFIER", "BOSA_IDENTIFIER"),
40
+ }
29
41
  _TOP_LEVEL_KEYS: tuple[str, ...] = (
30
42
  "token",
31
43
  "identifier",
@@ -54,7 +66,9 @@ class _InjectedTool(BaseTool):
54
66
  Returns:
55
67
  None
56
68
  """
57
- base_fields = {field: getattr(base_tool, field) for field in BaseTool.model_fields}
69
+ base_fields = {
70
+ field: getattr(base_tool, field) for field in BaseTool.model_fields
71
+ }
58
72
  super().__init__(**base_fields)
59
73
  self._base_tool = base_tool
60
74
  self._token = token
@@ -84,7 +98,9 @@ class _InjectedTool(BaseTool):
84
98
  """
85
99
  return await self._base_tool._arun(*args, **kwargs)
86
100
 
87
- def invoke(self, input: Any, config: RunnableConfig | None = None, **kwargs: Any) -> Any:
101
+ def invoke(
102
+ self, input: Any, config: RunnableConfig | None = None, **kwargs: Any
103
+ ) -> Any:
88
104
  """Invoke the tool with token and optional identifier injected.
89
105
 
90
106
  Args:
@@ -98,7 +114,9 @@ class _InjectedTool(BaseTool):
98
114
  injected = _inject_params(input, self._token, self._identifier, self._base_tool)
99
115
  return super().invoke(injected, config=config, **kwargs)
100
116
 
101
- async def ainvoke(self, input: Any, config: RunnableConfig | None = None, **kwargs: Any) -> Any:
117
+ async def ainvoke(
118
+ self, input: Any, config: RunnableConfig | None = None, **kwargs: Any
119
+ ) -> Any:
102
120
  """Invoke the tool asynchronously with token and optional identifier injected.
103
121
 
104
122
  Args:
@@ -122,7 +140,9 @@ class _InjectedTool(BaseTool):
122
140
  Returns:
123
141
  The result of running the tool with injected parameters.
124
142
  """
125
- injected = _inject_params(tool_input, self._token, self._identifier, self._base_tool)
143
+ injected = _inject_params(
144
+ tool_input, self._token, self._identifier, self._base_tool
145
+ )
126
146
  return super().run(injected, **kwargs)
127
147
 
128
148
  async def arun(self, tool_input: Any, **kwargs: Any) -> Any:
@@ -135,7 +155,9 @@ class _InjectedTool(BaseTool):
135
155
  Returns:
136
156
  The result of running the tool with injected parameters.
137
157
  """
138
- injected = _inject_params(tool_input, self._token, self._identifier, self._base_tool)
158
+ injected = _inject_params(
159
+ tool_input, self._token, self._identifier, self._base_tool
160
+ )
139
161
  return await super().arun(injected, **kwargs)
140
162
 
141
163
 
@@ -145,12 +167,12 @@ def GLConnectorTool(
145
167
  api_key: str | None = None,
146
168
  identifier: str | None = None,
147
169
  ) -> BaseTool:
148
- """Create a single GL Connector tool by exact tool name.
170
+ """Create a single tool from GL Connectors by exact tool name.
149
171
 
150
172
  Args:
151
173
  tool_name: Exact tool name (not module name).
152
- api_key: Optional override for BOSA API key.
153
- identifier: Optional override for BOSA identifier.
174
+ api_key: Optional override for GL Connectors API key.
175
+ identifier: Optional override for GL Connectors identifier.
154
176
 
155
177
  Returns:
156
178
  A single LangChain BaseTool with token injection.
@@ -159,14 +181,17 @@ def GLConnectorTool(
159
181
  raise ValueError("tool_name must be a non-empty string")
160
182
 
161
183
  env_values = _load_env(api_key=api_key, identifier=identifier)
162
- connector = BosaConnector(api_base_url=env_values["BOSA_BASE_URL"], api_key=env_values["BOSA_API_KEY"])
184
+ connector = BosaConnector(
185
+ api_base_url=env_values["GL_CONNECTORS_BASE_URL"],
186
+ api_key=env_values["GL_CONNECTORS_API_KEY"],
187
+ )
163
188
 
164
189
  modules = _get_available_modules(connector)
165
190
  module_name = _resolve_module(tool_name, modules)
166
191
 
167
192
  generator = BOSAConnectorToolGenerator(
168
- api_base_url=env_values["BOSA_BASE_URL"],
169
- api_key=env_values["BOSA_API_KEY"],
193
+ api_base_url=env_values["GL_CONNECTORS_BASE_URL"],
194
+ api_key=env_values["GL_CONNECTORS_API_KEY"],
170
195
  app_name=module_name,
171
196
  )
172
197
  tools = generator.generate_tools(tool_type=ToolType.LANGCHAIN)
@@ -175,18 +200,24 @@ def GLConnectorTool(
175
200
  if not matching:
176
201
  raise ValueError(f"Tool '{tool_name}' not found in module '{module_name}'")
177
202
  if len(matching) > 1:
178
- raise ValueError(f"Multiple tools named '{tool_name}' found in module '{module_name}'")
179
-
180
- token = _create_token(connector, env_values["BOSA_USERNAME"], env_values["BOSA_PASSWORD"])
181
- return _InjectedTool(matching[0], token, env_values.get("BOSA_IDENTIFIER"))
203
+ raise ValueError(
204
+ f"Multiple tools named '{tool_name}' found in module '{module_name}'"
205
+ )
206
+
207
+ token = _create_token(
208
+ connector,
209
+ env_values["GL_CONNECTORS_USERNAME"],
210
+ env_values["GL_CONNECTORS_PASSWORD"],
211
+ )
212
+ return _InjectedTool(matching[0], token, env_values.get("GL_CONNECTORS_IDENTIFIER"))
182
213
 
183
214
 
184
215
  def _load_env(*, api_key: str | None, identifier: str | None) -> dict[str, str]:
185
216
  """Load and validate environment configuration for connector access.
186
217
 
187
218
  Args:
188
- api_key: Optional override for BOSA API key.
189
- identifier: Optional override for BOSA identifier.
219
+ api_key: Optional override for GL Connectors API key.
220
+ identifier: Optional override for GL Connectors identifier.
190
221
 
191
222
  Returns:
192
223
  Dictionary containing environment configuration values.
@@ -194,28 +225,42 @@ def _load_env(*, api_key: str | None, identifier: str | None) -> dict[str, str]:
194
225
  Raises:
195
226
  ValueError: If required environment variables are missing.
196
227
  """
197
- env = {key: os.getenv(key) for key in _REQUIRED_ENV_VARS}
228
+ env: dict[str, str | None] = {}
198
229
 
199
- resolved_api_key = api_key or env["BOSA_API_KEY"]
200
- env["BOSA_API_KEY"] = resolved_api_key
230
+ # Load from environment using mapping (prefers GL_CONNECTORS_* over BOSA_*)
231
+ for internal_key, env_vars in _ENV_VAR_MAPPING.items():
232
+ val = None
233
+ for var_name in env_vars:
234
+ val = os.getenv(var_name)
235
+ if val:
236
+ break
237
+ env[internal_key] = val
201
238
 
202
- optional_identifier = identifier or os.getenv("BOSA_IDENTIFIER")
239
+ if api_key:
240
+ env["GL_CONNECTORS_API_KEY"] = api_key
203
241
 
204
- if optional_identifier:
205
- env["BOSA_IDENTIFIER"] = optional_identifier
242
+ if identifier:
243
+ env["GL_CONNECTORS_IDENTIFIER"] = identifier
206
244
 
207
- missing = [key for key, value in env.items() if key in _REQUIRED_ENV_VARS and not value]
245
+ missing = [key for key in _REQUIRED_ENV_VARS if not env.get(key)]
208
246
  if missing:
209
- raise ValueError(f"Missing required environment variables: {', '.join(missing)}")
247
+ # Map back to human-friendly names for the error message
248
+ friendly_missing = []
249
+ for m in missing:
250
+ preferred = _ENV_VAR_MAPPING[m][0]
251
+ friendly_missing.append(preferred)
252
+ raise ValueError(
253
+ f"Missing required environment variables: {', '.join(friendly_missing)}"
254
+ )
210
255
 
211
- return {key: value for key, value in env.items() if value is not None}
256
+ return {k: v for k, v in env.items() if v is not None}
212
257
 
213
258
 
214
259
  def _get_available_modules(connector: BosaConnector) -> list[str]:
215
260
  """Return available connector modules or raise an actionable error.
216
261
 
217
262
  Args:
218
- connector: BOSA connector instance to query for modules.
263
+ connector: GL Connectors instance to query for modules.
219
264
 
220
265
  Returns:
221
266
  List of available module names.
@@ -246,13 +291,21 @@ def _resolve_module(tool_name: str, modules: Iterable[str]) -> str:
246
291
  Raises:
247
292
  ValueError: If no matching module is found or multiple ambiguous matches exist.
248
293
  """
249
- candidates = [module for module in modules if tool_name == module or tool_name.startswith(f"{module}_")]
294
+ candidates = [
295
+ module
296
+ for module in modules
297
+ if tool_name == module or tool_name.startswith(f"{module}_")
298
+ ]
250
299
  if not candidates:
251
- raise ValueError(f"Unable to resolve module for tool '{tool_name}'. Available modules: {', '.join(modules)}")
300
+ raise ValueError(
301
+ f"Unable to resolve module for tool '{tool_name}'. Available modules: {', '.join(modules)}"
302
+ )
252
303
 
253
304
  candidates.sort(key=len, reverse=True)
254
305
  if len(candidates) > 1 and len(candidates[0]) == len(candidates[1]):
255
- raise ValueError(f"Ambiguous module match for tool '{tool_name}'. Matches: {', '.join(candidates)}")
306
+ raise ValueError(
307
+ f"Ambiguous module match for tool '{tool_name}'. Matches: {', '.join(candidates)}"
308
+ )
256
309
  return candidates[0]
257
310
 
258
311
 
@@ -260,9 +313,9 @@ def _create_token(connector: BosaConnector, username: str, password: str) -> str
260
313
  """Authenticate the connector user and return a user token.
261
314
 
262
315
  Args:
263
- connector: BOSA connector instance for authentication.
264
- username: BOSA username for authentication.
265
- password: BOSA password for authentication.
316
+ connector: GL Connectors instance for authentication.
317
+ username: GL Connectors username for authentication.
318
+ password: GL Connectors password for authentication.
266
319
 
267
320
  Returns:
268
321
  Authentication token string.
@@ -273,15 +326,17 @@ def _create_token(connector: BosaConnector, username: str, password: str) -> str
273
326
  try:
274
327
  user = connector.authenticate_bosa_user(username, password)
275
328
  except Exception as exc:
276
- raise ValueError("Failed to authenticate BOSA user") from exc
329
+ raise ValueError("Failed to authenticate GL Connectors user") from exc
277
330
 
278
331
  token = getattr(user, "token", None)
279
332
  if not token:
280
- raise ValueError("BOSA user token missing after authentication")
333
+ raise ValueError("GL Connectors user token missing after authentication")
281
334
  return token
282
335
 
283
336
 
284
- def _inject_params(tool_input: Any, token: str, identifier: str | None, base_tool: BaseTool) -> dict[str, Any]:
337
+ def _inject_params(
338
+ tool_input: Any, token: str, identifier: str | None, base_tool: BaseTool
339
+ ) -> dict[str, Any]:
285
340
  """Inject token and optional identifier into tool input.
286
341
 
287
342
  Args:
@@ -319,7 +374,9 @@ def _inject_params(tool_input: Any, token: str, identifier: str | None, base_too
319
374
  return injected
320
375
 
321
376
 
322
- def _wrap_request_if_needed(tool_input: dict[str, Any], base_tool: BaseTool) -> dict[str, Any]:
377
+ def _wrap_request_if_needed(
378
+ tool_input: dict[str, Any], base_tool: BaseTool
379
+ ) -> dict[str, Any]:
323
380
  """Wrap flat inputs into a 'request' payload when required by schema.
324
381
 
325
382
  Args:
@@ -330,7 +387,9 @@ def _wrap_request_if_needed(tool_input: dict[str, Any], base_tool: BaseTool) ->
330
387
  Dictionary with inputs wrapped in 'request' key if needed, otherwise unchanged.
331
388
  """
332
389
  args_schema = getattr(base_tool, "args_schema", None)
333
- if not (isinstance(args_schema, dict) and "request" in args_schema.get("properties", {})):
390
+ if not (
391
+ isinstance(args_schema, dict) and "request" in args_schema.get("properties", {})
392
+ ):
334
393
  return tool_input
335
394
 
336
395
  request_payload = {}
@@ -62,12 +62,12 @@ class _InjectedTool(BaseTool):
62
62
  """
63
63
 
64
64
  def GLConnectorTool(tool_name: str, *, api_key: str | None = None, identifier: str | None = None) -> BaseTool:
65
- """Create a single GL Connector tool by exact tool name.
65
+ """Create a single tool from GL Connectors by exact tool name.
66
66
 
67
67
  Args:
68
68
  tool_name: Exact tool name (not module name).
69
- api_key: Optional override for BOSA API key.
70
- identifier: Optional override for BOSA identifier.
69
+ api_key: Optional override for GL Connectors API key.
70
+ identifier: Optional override for GL Connectors identifier.
71
71
 
72
72
  Returns:
73
73
  A single LangChain BaseTool with token injection.
@@ -0,0 +1,122 @@
1
+ """Auto-generated tools from GL Connectors.
2
+
3
+ Authors:
4
+ Saul Sayers (saul.sayers@gdplabs.id)
5
+ """
6
+
7
+ from aip_agents.tools.constants import (
8
+ GL_CONNECTORS_API_KEY,
9
+ GL_CONNECTORS_BASE_URL,
10
+ GL_CONNECTORS_FETCH_MAX_RETRIES,
11
+ ToolType,
12
+ )
13
+ from aip_agents.utils.logger import get_logger
14
+ from bosa_connectors import BosaConnector, BOSAConnectorToolGenerator
15
+ from langchain_core.tools import BaseTool
16
+
17
+ logger = get_logger(__name__)
18
+
19
+
20
+ def get_gl_connector_modules_with_retry() -> list[str]:
21
+ """Try to get available modules with retries.
22
+
23
+ Returns:
24
+ List of available modules.
25
+ """
26
+ if not GL_CONNECTORS_BASE_URL or not GL_CONNECTORS_API_KEY:
27
+ logger.warning(
28
+ "GL Connectors credentials missing (base_url or api_key); returning empty modules list"
29
+ )
30
+ return []
31
+
32
+ connector = BosaConnector(
33
+ api_base_url=GL_CONNECTORS_BASE_URL, api_key=GL_CONNECTORS_API_KEY
34
+ )
35
+ modules = []
36
+ for attempt in range(GL_CONNECTORS_FETCH_MAX_RETRIES):
37
+ try:
38
+ modules = list(connector.get_available_modules())
39
+ if modules:
40
+ return modules
41
+ logger.warning(
42
+ f"Failed to get GL Connectors available modules, retrying... (attempt {attempt + 1} / {GL_CONNECTORS_FETCH_MAX_RETRIES})"
43
+ )
44
+ except Exception as e:
45
+ logger.exception(
46
+ f"Exception when getting GL Connectors available modules (attempt {attempt + 1} / {GL_CONNECTORS_FETCH_MAX_RETRIES}): {e}"
47
+ )
48
+ logger.error("Failed to get GL Connectors available modules after maximum retries")
49
+ return modules
50
+
51
+
52
+ class LazyGLConnectorToolsDict(dict):
53
+ """Lazy dictionary for GL Connectors."""
54
+
55
+ def __missing__(self, app):
56
+ """When a key is missing, create the tools and store them in the dictionary.
57
+
58
+ Args:
59
+ app: Name of the GL Connectors.
60
+
61
+ Returns:
62
+ List of tools generated by the GL Connectors tool generator.
63
+ """
64
+ if app not in get_gl_connector_modules():
65
+ return []
66
+ tools = []
67
+ for attempt in range(GL_CONNECTORS_FETCH_MAX_RETRIES):
68
+ try:
69
+ tools = BOSAConnectorToolGenerator(
70
+ api_base_url=GL_CONNECTORS_BASE_URL,
71
+ api_key=GL_CONNECTORS_API_KEY,
72
+ app_name=app,
73
+ ).generate_tools(tool_type=ToolType.LANGCHAIN)
74
+ if tools:
75
+ self[app] = tools
76
+ return tools
77
+ logger.warning(
78
+ f"Failed to create GL Connectors, retrying... (attempt {attempt + 1} / {GL_CONNECTORS_FETCH_MAX_RETRIES})"
79
+ )
80
+ except Exception as e:
81
+ logger.exception(
82
+ f"Exception when creating GL Connectors for app '{app}' "
83
+ f"(attempt {attempt + 1} / {GL_CONNECTORS_FETCH_MAX_RETRIES}): {e}"
84
+ )
85
+ logger.error("Failed to create GL Connectors after maximum retries")
86
+ return tools
87
+
88
+
89
+ # Supported modules (dynamic)
90
+ def get_gl_connector_modules() -> list[str]:
91
+ """Lazily fetch and cache GL Connectors modules.
92
+
93
+ Returns:
94
+ List of GL Connectors modules.
95
+ """
96
+ if not hasattr(get_gl_connector_modules, "_cache"):
97
+ get_gl_connector_modules._cache = get_gl_connector_modules_with_retry()
98
+ return get_gl_connector_modules._cache
99
+
100
+
101
+ # FOR BACKWARDS COMPATIBILITY
102
+ def get_bosa_modules() -> list[str]:
103
+ """Backward-compatible alias for get_gl_connector_modules."""
104
+ return get_gl_connector_modules()
105
+
106
+
107
+ GL_CONNECTORS_MODULES = [
108
+ "github",
109
+ "twitter",
110
+ "google",
111
+ "google_drive",
112
+ "google_mail",
113
+ "google_docs",
114
+ ]
115
+
116
+ # FOR BACKWARDS COMPATIBILITY
117
+ BOSA_MODULES = GL_CONNECTORS_MODULES
118
+
119
+ GL_CONNECTORS_AUTOMATED_TOOLS: dict[str, list[BaseTool]] = LazyGLConnectorToolsDict()
120
+
121
+ # FOR BACKWARDS COMPATIBILITY
122
+ BOSA_AUTOMATED_TOOLS = GL_CONNECTORS_AUTOMATED_TOOLS
@@ -0,0 +1,39 @@
1
+ from _typeshed import Incomplete
2
+ from aip_agents.tools.constants import GL_CONNECTORS_API_KEY as GL_CONNECTORS_API_KEY, GL_CONNECTORS_BASE_URL as GL_CONNECTORS_BASE_URL, GL_CONNECTORS_FETCH_MAX_RETRIES as GL_CONNECTORS_FETCH_MAX_RETRIES, ToolType as ToolType
3
+ from aip_agents.utils.logger import get_logger as get_logger
4
+ from langchain_core.tools import BaseTool as BaseTool
5
+
6
+ logger: Incomplete
7
+
8
+ def get_gl_connector_modules_with_retry() -> list[str]:
9
+ """Try to get available modules with retries.
10
+
11
+ Returns:
12
+ List of available modules.
13
+ """
14
+
15
+ class LazyGLConnectorToolsDict(dict):
16
+ """Lazy dictionary for GL Connectors."""
17
+ def __missing__(self, app):
18
+ """When a key is missing, create the tools and store them in the dictionary.
19
+
20
+ Args:
21
+ app: Name of the GL Connectors.
22
+
23
+ Returns:
24
+ List of tools generated by the GL Connectors tool generator.
25
+ """
26
+
27
+ def get_gl_connector_modules() -> list[str]:
28
+ """Lazily fetch and cache GL Connectors modules.
29
+
30
+ Returns:
31
+ List of GL Connectors modules.
32
+ """
33
+ def get_bosa_modules() -> list[str]:
34
+ """Backward-compatible alias for get_gl_connector_modules."""
35
+
36
+ GL_CONNECTORS_MODULES: Incomplete
37
+ BOSA_MODULES = GL_CONNECTORS_MODULES
38
+ GL_CONNECTORS_AUTOMATED_TOOLS: dict[str, list[BaseTool]]
39
+ BOSA_AUTOMATED_TOOLS = GL_CONNECTORS_AUTOMATED_TOOLS
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: aip-agents-binary
3
- Version: 0.5.20
3
+ Version: 0.5.22
4
4
  Summary: A library for managing agents in Gen AI applications.
5
5
  Author-email: Raymond Christopher <raymond.christopher@gdplabs.id>
6
6
  Requires-Python: <3.13,>=3.11
@@ -159,9 +159,9 @@ Navigate to the library's root directory (e.g., `python/aip-agents` if you clone
159
159
  python aip_agents/examples/hello_world_langgraph.py
160
160
  ```
161
161
 
162
- **LangGraph with BOSA Connector (OpenAI):**
162
+ **LangGraph with GL Connectors (OpenAI):**
163
163
  ```bash
164
- python aip_agents/examples/hello_world_langgraph_bosa_twitter.py
164
+ python aip_agents/examples/hello_world_langgraph_gl_connector_twitter.py
165
165
  ```
166
166
 
167
167
  **LangGraph Streaming (OpenAI):**
@@ -179,8 +179,8 @@ aip_agents/examples/hello_world_langflow_agent.py,sha256=NFgI_jJ0mDpeRpVhw5TESRS
179
179
  aip_agents/examples/hello_world_langflow_agent.pyi,sha256=sl3sF36CcY_s_zQ61gvneRyTiHmPV8p9xzPL2IeB1zo,1251
180
180
  aip_agents/examples/hello_world_langgraph.py,sha256=CSlZzVOtwbnCxw3uci_qGFzO7eYZe0uzs-4kmGNih7A,1248
181
181
  aip_agents/examples/hello_world_langgraph.pyi,sha256=ix3j1wqj79wkMMuOjEQUhZA4Isr5JSFEJw49WJ2NmM4,251
182
- aip_agents/examples/hello_world_langgraph_bosa_twitter.py,sha256=NmRmEU6bccPa7UNRw1RCxYrcgw6RaLU2HYgmfy6V4IY,1224
183
- aip_agents/examples/hello_world_langgraph_bosa_twitter.pyi,sha256=QSx4K8FDnQzedl3Cl5ZlngL1-HEjE7MiLSemQ2N0dsU,238
182
+ aip_agents/examples/hello_world_langgraph_gl_connector_twitter.py,sha256=rZ517PtYjE9azJjtSOXkZgyc_g7pHejVS7Ij4gz-BqE,1327
183
+ aip_agents/examples/hello_world_langgraph_gl_connector_twitter.pyi,sha256=zvvkXFJw8NV4W7B8XB4b4F3s-HKixsasSMfJAuteqoQ,264
184
184
  aip_agents/examples/hello_world_langgraph_mcp_http.py,sha256=BmfwomTLNbGH3jpMMxGmSV_waYuvfbtdYdeKqVVzEPw,1008
185
185
  aip_agents/examples/hello_world_langgraph_mcp_http.pyi,sha256=8Ye3T6ip-_qykUEsYz5oPrJ99Td89OvFYwTdiP6-hAk,264
186
186
  aip_agents/examples/hello_world_langgraph_mcp_http_stream.py,sha256=h2nkg-oeZvzFWF2k2LHvAOiUqfnpnGAk1sfK1JiVQlg,1129
@@ -209,7 +209,7 @@ aip_agents/examples/hello_world_multi_agent_langgraph_lm_invoker.py,sha256=sppLD
209
209
  aip_agents/examples/hello_world_multi_agent_langgraph_lm_invoker.pyi,sha256=zFNns9i-sPY8aBy4HaVS6tXDWTsU7f-ApLD8gDtb1uk,252
210
210
  aip_agents/examples/hello_world_pii_logger.py,sha256=pm9LK-doZwQL-VdJYFHziuvwH562c8wwAwmKZeAWQS0,584
211
211
  aip_agents/examples/hello_world_pii_logger.pyi,sha256=5gOVrvhQV2DxIwr7ocL1-oTUXsO8XSyl5WN70c7rl_w,134
212
- aip_agents/examples/hello_world_sentry.py,sha256=V-q6r9Nw76XosFGxIAxVtbpp_WmncgqU0PoBwMNBXXY,3958
212
+ aip_agents/examples/hello_world_sentry.py,sha256=UI9bkfoui4SjhHWSllJGUdaup3kYzGtoomZkY1zhcXg,4005
213
213
  aip_agents/examples/hello_world_sentry.pyi,sha256=k0wFj46QqXEjBU0CEERmiEf2bovVFkupzuzQzeD6h00,671
214
214
  aip_agents/examples/hello_world_step_limits.py,sha256=hRV9XERlq2qW_yZ4kHAe1hTgukrSZjThIrsY9NuTdJg,9809
215
215
  aip_agents/examples/hello_world_step_limits.pyi,sha256=V9KP6r5OEVq2lNUfnqMeCGH1nsNewDsRL1Uo9up8xis,1060
@@ -348,10 +348,10 @@ aip_agents/schema/step_limit.py,sha256=8hqHSxHBWro8qvNR0pMxROpFSzlLqcyFO4veS_WDP
348
348
  aip_agents/schema/step_limit.pyi,sha256=UvLDMTy8BI7h1Jx5gpbpw1jrJ9L5vK8cmQkvQdlD3bs,2318
349
349
  aip_agents/schema/storage.py,sha256=Tl0RFT32GWdsc5y8bTvpWMOU8hmQxXIlrMub3qdwx8Y,1290
350
350
  aip_agents/schema/storage.pyi,sha256=exaZAS49PYSuhYSPYukIRCRHIGRyCpBGucrdpnhV4zE,557
351
- aip_agents/sentry/__init__.py,sha256=S1XFjmAnNsqnI_Jk_ozNqDodkqWgzZ8xZPTXS2zqXzI,252
351
+ aip_agents/sentry/__init__.py,sha256=l3nI-3pjBNNmcOZ7xPeIis1n_wkPpvnk2aHxQYWsflU,261
352
352
  aip_agents/sentry/__init__.pyi,sha256=OGxzQzEvbnqf02zXdBJUrHeKfjfBgvnOL7p-0gNvP8k,103
353
- aip_agents/sentry/sentry.py,sha256=LlahQ2bkjL9FSFH0RoCdMDLhyXEUAj3zHkK_xxMQIKo,4501
354
- aip_agents/sentry/sentry.pyi,sha256=G9YgWGIqHskkfj9aXN-Y6RLe3tvDvYi_RSkW1Y_MFzE,1436
353
+ aip_agents/sentry/sentry.py,sha256=DgYaIph-VQp0b36sUFvBqxe9lmbBZv1i1edg0Tx5nbE,4595
354
+ aip_agents/sentry/sentry.pyi,sha256=fTFb71FfeByBUIACjkp8qaHsWe6C52Y4tPTfizAPVv0,1432
355
355
  aip_agents/storage/__init__.py,sha256=cN4L2whui-DOm81tsYV88Wx5g5-cUjeLVyp55RtbJJU,1219
356
356
  aip_agents/storage/__init__.pyi,sha256=wn8VuS7x4WSzKuV01WrjPkZfnh3GylNum9FlPiaSdsA,901
357
357
  aip_agents/storage/base.py,sha256=dijzGJJRHPEneV-6QRC_xm0CzgYuIyhmnWloJC8oIx0,2413
@@ -370,12 +370,12 @@ aip_agents/storage/providers/memory.py,sha256=81E9yT_oRkH7tMVr5azZv1oXIaeTzTAtTu
370
370
  aip_agents/storage/providers/memory.pyi,sha256=r0meeCsjKyE9FHJqCysfQ5ZH_FWRRv2SWg-NOHCUD-g,2109
371
371
  aip_agents/storage/providers/object_storage.py,sha256=Q268Sn8Y09gS-ilP6fe4CR0YIOvdbunh3V6SmuQsAVs,6413
372
372
  aip_agents/storage/providers/object_storage.pyi,sha256=nBIKJjUAWkIKhYhBFmFcypjoOieIYOghy55f62x7AX8,2878
373
- aip_agents/tools/__init__.py,sha256=9nQiB63jqn0G45fN3rF7wXmYOn2TrWASGbHBPr6LTd4,1199
374
- aip_agents/tools/__init__.pyi,sha256=ViizRq0Pv0cFxX90X6WoXZPcWrZ4-dJzbOnw5UgWUmc,619
375
- aip_agents/tools/bosa_tools.py,sha256=uhRImaIACt_Ol9nraUGr0ddT8e35c8doVzwlJV6kGeA,3411
376
- aip_agents/tools/bosa_tools.pyi,sha256=GpWQhkytk4XS_rKWGBiS70y5mXC8b-1GGCkN1BaE97s,1128
377
- aip_agents/tools/constants.py,sha256=pVmUJx8WN1gYtDT52B4FsetnaYZZWozKQQ7wW18xIHo,5274
378
- aip_agents/tools/constants.pyi,sha256=QucwMEKTXywF72m8ofImoswbj6zA-BsfP0tRaIy7A6Y,3393
373
+ aip_agents/tools/__init__.py,sha256=HWj2nsjMBadA6aJdPlBQBSBxbvDAYmMKe3PJeNyDRbA,1935
374
+ aip_agents/tools/__init__.pyi,sha256=w1gRWL5iRdLtuBNXBhmD87uzfvIRrXwq3uZ1meku8js,888
375
+ aip_agents/tools/constants.py,sha256=S8-ctDo4FXp5Si8dFCJ2FORPPS1SKD2OQT5II3j1yak,5731
376
+ aip_agents/tools/constants.pyi,sha256=kFY8dKgRqHKGvPqG3QUyuEc8C5yRaDj7DYQDH88K2T0,3552
377
+ aip_agents/tools/gl_connector_tools.py,sha256=yXLuGTTAUxCYpOG808pKcHEZIntNI_x-JUq3OqzxexI,3971
378
+ aip_agents/tools/gl_connector_tools.pyi,sha256=2ATn_MW_FRg5Uv7dLI_ToBOtlgTSfj0zgDQpN1N-cJs,1366
379
379
  aip_agents/tools/memory_search_tool.py,sha256=gqTTb_Fao_Hl-SavfaFsqPDhnFQUjzIQUkzizSD2L0A,653
380
380
  aip_agents/tools/memory_search_tool.pyi,sha256=BCVFEEgH3pETnI9b6vRlMm2_PnnIeBe_vuMlL9y3LpU,453
381
381
  aip_agents/tools/time_tool.py,sha256=NPjz73hy1SNc3okWhDXdR45q84vmRUerDGDk_E-XyZk,3732
@@ -428,10 +428,10 @@ aip_agents/tools/document_loader/pdf_reader_tool.py,sha256=36U_r7E0n_nLl4xUXC4nD
428
428
  aip_agents/tools/document_loader/pdf_reader_tool.pyi,sha256=ZKr5E3ePTJWHdLfM3_7Ji9NGDpL29uKLFhLl-smZQqQ,494
429
429
  aip_agents/tools/document_loader/pdf_splitter.py,sha256=-QyrlnN4AXDqY_dxeUzxcgCVJJiD1vYUYR7swfhM_RQ,5752
430
430
  aip_agents/tools/document_loader/pdf_splitter.pyi,sha256=3IiRDQWDz8QR5LH_sni9O-N2qJFheFjKOQMAhiWxB7E,716
431
- aip_agents/tools/gl_connector/__init__.py,sha256=tpQ0vF7gMiyO32jTBndOAVor5MRDNff7yh_SC7Frv_U,136
431
+ aip_agents/tools/gl_connector/__init__.py,sha256=f8F4mdBFj0ulxewCQwG5qN2SDzlgI2jA0Kfj31A5iD0,137
432
432
  aip_agents/tools/gl_connector/__init__.pyi,sha256=96wtNkB3VUSI66aRlYxVrzMiPtqOYviRMKviRgX3_fc,113
433
- aip_agents/tools/gl_connector/tool.py,sha256=FaS8B6lJI4RuB5NoirqezIBQhsVb4ymUBvItJXtdWMc,11999
434
- aip_agents/tools/gl_connector/tool.pyi,sha256=u6GQCwxqFLVhZVYeTek6ExEvrhPTF7z1QCHcRtcgFqU,2746
433
+ aip_agents/tools/gl_connector/tool.py,sha256=EmfAYU5ZEtG93osWPWd4ElfXIhBe7mqz0yIH6Ntc9sE,13343
434
+ aip_agents/tools/gl_connector/tool.pyi,sha256=a5l0MHSOe_iWDvjMRzYtcbMdX0bFlK1m7Hl52HQ__iQ,2770
435
435
  aip_agents/tools/memory_search/__init__.py,sha256=YSsObYlHjdZEbJj4MVYy3Ht8JPlo42YhjnkI-yFNWV0,608
436
436
  aip_agents/tools/memory_search/__init__.pyi,sha256=NG0g94OoC_xw66yIqiPViqTnpj01QdnRsVBGzkSxJFI,554
437
437
  aip_agents/tools/memory_search/base.py,sha256=M4Vq5CnXge1rhVkESfVCAjyWEc6Ijmh8-6oAMkcZkjY,7333
@@ -540,7 +540,7 @@ aip_agents/utils/pii/pii_helper.py,sha256=g0yRzakfA2AA6vjUNLWHqFlcxyLql6MXQ90NN3
540
540
  aip_agents/utils/pii/pii_helper.pyi,sha256=dulZs150ikbAL3Bw2YLcz3_g4DsGmL3lciwf8mKxEjI,2939
541
541
  aip_agents/utils/pii/uuid_deanonymizer_mapping.py,sha256=Gks8l8t0cuS9pzoQnrpiK1CaLmWYksjOnTeiHh3_7EE,7348
542
542
  aip_agents/utils/pii/uuid_deanonymizer_mapping.pyi,sha256=gnWfD1rWZh_tloJjgKiZ6f6iNUuBaHpKqCSiP0d-9bs,3084
543
- aip_agents_binary-0.5.20.dist-info/METADATA,sha256=mfxqDEti6yRl2Rh5gjxpO278NjMj1UfGq41na3pT_jE,22207
544
- aip_agents_binary-0.5.20.dist-info/WHEEL,sha256=PaP4PvkDyiSc4C6Dhw6ccQmfxsWFrSv-lJQjBshu0hw,105
545
- aip_agents_binary-0.5.20.dist-info/top_level.txt,sha256=PEz8vcwC1bH4UrkhF0LkIYCNfXGWZUHdSklbvkBe25E,11
546
- aip_agents_binary-0.5.20.dist-info/RECORD,,
543
+ aip_agents_binary-0.5.22.dist-info/METADATA,sha256=CocpyU4hmWP-sT9ti3uGtzFDcULe2Vr2sJVH-Ae2ftM,22214
544
+ aip_agents_binary-0.5.22.dist-info/WHEEL,sha256=PaP4PvkDyiSc4C6Dhw6ccQmfxsWFrSv-lJQjBshu0hw,105
545
+ aip_agents_binary-0.5.22.dist-info/top_level.txt,sha256=PEz8vcwC1bH4UrkhF0LkIYCNfXGWZUHdSklbvkBe25E,11
546
+ aip_agents_binary-0.5.22.dist-info/RECORD,,
@@ -1,5 +0,0 @@
1
- from aip_agents.agent import LangGraphAgent as LangGraphAgent
2
- from aip_agents.tools import BOSA_AUTOMATED_TOOLS as BOSA_AUTOMATED_TOOLS
3
-
4
- async def langgraph_bosa_example() -> None:
5
- """Demonstrates the LangGraphAgent's arun method."""
@@ -1,105 +0,0 @@
1
- """Auto-generated tools from BOSA connector.
2
-
3
- Authors:
4
- Saul Sayers (saul.sayers@gdplabs.id)
5
- """
6
-
7
- from bosa_connectors import BosaConnector, BOSAConnectorToolGenerator
8
- from langchain_core.tools import BaseTool
9
-
10
- from aip_agents.tools.constants import BOSA_API_BASE_URL, BOSA_API_KEY, BOSA_FETCH_MAX_RETRIES, ToolType
11
- from aip_agents.utils.logger import get_logger
12
-
13
- logger = get_logger(__name__)
14
-
15
-
16
- def get_bosa_modules_with_retry() -> list[str]:
17
- """Try to get available modules with retries.
18
-
19
- Returns:
20
- List of available modules.
21
- """
22
- if not BOSA_API_BASE_URL or not BOSA_API_KEY:
23
- logger.warning("BOSA credentials missing (base_url or api_key); returning empty modules list")
24
- return []
25
-
26
- connector = BosaConnector(api_base_url=BOSA_API_BASE_URL, api_key=BOSA_API_KEY)
27
- modules = []
28
- for attempt in range(BOSA_FETCH_MAX_RETRIES):
29
- try:
30
- modules = list(connector.get_available_modules())
31
- if modules:
32
- return modules
33
- logger.warning(
34
- f"Failed to get BOSA available modules, retrying... (attempt {attempt + 1} / {BOSA_FETCH_MAX_RETRIES})"
35
- )
36
- except Exception as e:
37
- logger.exception(
38
- f"Exception when getting BOSA available modules (attempt {attempt + 1} / {BOSA_FETCH_MAX_RETRIES}): {e}"
39
- )
40
- logger.error("Failed to get BOSA available modules after maximum retries")
41
- return modules
42
-
43
-
44
- class LazyBosaToolsDict(dict):
45
- """Lazy dictionary for BOSA tools."""
46
-
47
- def __missing__(self, app):
48
- """When a key is missing, create the tools and store them in the dictionary.
49
-
50
- Args:
51
- app: Name of the BOSA connector.
52
-
53
- Returns:
54
- List of tools generated by BOSAConnectorToolGenerator.
55
- """
56
- if app not in get_bosa_modules():
57
- return []
58
- tools = []
59
- for attempt in range(BOSA_FETCH_MAX_RETRIES):
60
- try:
61
- tools = BOSAConnectorToolGenerator(
62
- api_base_url=BOSA_API_BASE_URL,
63
- api_key=BOSA_API_KEY,
64
- app_name=app,
65
- ).generate_tools(tool_type=ToolType.LANGCHAIN)
66
- if tools:
67
- self[app] = tools
68
- return tools
69
- logger.warning(
70
- f"Failed to create BOSA tools, retrying... (attempt {attempt + 1} / {BOSA_FETCH_MAX_RETRIES})"
71
- )
72
- except Exception as e:
73
- logger.exception(
74
- f"Exception when creating BOSA tools for app '{app}' "
75
- f"(attempt {attempt + 1} / {BOSA_FETCH_MAX_RETRIES}): {e}"
76
- )
77
- logger.error("Failed to create BOSA tools after maximum retries")
78
- return tools
79
-
80
-
81
- # Supported modules (dynamic)
82
- def get_bosa_modules() -> list[str]:
83
- """Lazily fetch and cache BOSA modules.
84
-
85
- This is for backwards compatibility with the old BOSA modules.
86
-
87
- Returns:
88
- List of BOSA modules.
89
- """
90
- if not hasattr(get_bosa_modules, "_cache"):
91
- get_bosa_modules._cache = get_bosa_modules_with_retry()
92
- return get_bosa_modules._cache
93
-
94
-
95
- # FOR BACKWARDS COMPATIBILITY
96
- BOSA_MODULES = [
97
- "github",
98
- "twitter",
99
- "google",
100
- "google_drive",
101
- "google_mail",
102
- "google_docs",
103
- ]
104
-
105
- BOSA_AUTOMATED_TOOLS: dict[str, list[BaseTool]] = LazyBosaToolsDict()
@@ -1,37 +0,0 @@
1
- from _typeshed import Incomplete
2
- from aip_agents.tools.constants import BOSA_API_BASE_URL as BOSA_API_BASE_URL, BOSA_API_KEY as BOSA_API_KEY, BOSA_FETCH_MAX_RETRIES as BOSA_FETCH_MAX_RETRIES, ToolType as ToolType
3
- from aip_agents.utils.logger import get_logger as get_logger
4
- from langchain_core.tools import BaseTool as BaseTool
5
-
6
- logger: Incomplete
7
-
8
- def get_bosa_modules_with_retry() -> list[str]:
9
- """Try to get available modules with retries.
10
-
11
- Returns:
12
- List of available modules.
13
- """
14
-
15
- class LazyBosaToolsDict(dict):
16
- """Lazy dictionary for BOSA tools."""
17
- def __missing__(self, app):
18
- """When a key is missing, create the tools and store them in the dictionary.
19
-
20
- Args:
21
- app: Name of the BOSA connector.
22
-
23
- Returns:
24
- List of tools generated by BOSAConnectorToolGenerator.
25
- """
26
-
27
- def get_bosa_modules() -> list[str]:
28
- """Lazily fetch and cache BOSA modules.
29
-
30
- This is for backwards compatibility with the old BOSA modules.
31
-
32
- Returns:
33
- List of BOSA modules.
34
- """
35
-
36
- BOSA_MODULES: Incomplete
37
- BOSA_AUTOMATED_TOOLS: dict[str, list[BaseTool]]