aip-agents-binary 0.5.25b9__py3-none-any.whl → 0.6.1__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 aip-agents-binary might be problematic. Click here for more details.
- aip_agents/agent/base_langgraph_agent.py +137 -68
- aip_agents/agent/base_langgraph_agent.pyi +3 -2
- aip_agents/agent/langgraph_react_agent.py +252 -16
- aip_agents/agent/langgraph_react_agent.pyi +40 -1
- aip_agents/examples/compare_streaming_client.py +2 -2
- aip_agents/examples/compare_streaming_server.py +1 -1
- aip_agents/examples/hello_world_ptc.py +51 -0
- aip_agents/examples/hello_world_ptc.pyi +5 -0
- aip_agents/examples/hello_world_tool_output_client.py +9 -0
- aip_agents/examples/todolist_planning_a2a_langchain_client.py +2 -2
- aip_agents/examples/todolist_planning_a2a_langgraph_server.py +1 -1
- aip_agents/guardrails/engines/base.py +6 -6
- aip_agents/mcp/client/connection_manager.py +36 -1
- aip_agents/mcp/client/connection_manager.pyi +3 -0
- aip_agents/mcp/client/persistent_session.py +318 -68
- aip_agents/mcp/client/persistent_session.pyi +9 -0
- aip_agents/mcp/client/transports.py +33 -2
- aip_agents/mcp/client/transports.pyi +9 -0
- aip_agents/ptc/__init__.py +48 -0
- aip_agents/ptc/__init__.pyi +10 -0
- aip_agents/ptc/doc_gen.py +122 -0
- aip_agents/ptc/doc_gen.pyi +40 -0
- aip_agents/ptc/exceptions.py +39 -0
- aip_agents/ptc/exceptions.pyi +22 -0
- aip_agents/ptc/executor.py +143 -0
- aip_agents/ptc/executor.pyi +73 -0
- aip_agents/ptc/mcp/__init__.py +45 -0
- aip_agents/ptc/mcp/__init__.pyi +7 -0
- aip_agents/ptc/mcp/sandbox_bridge.py +668 -0
- aip_agents/ptc/mcp/sandbox_bridge.pyi +47 -0
- aip_agents/ptc/mcp/templates/__init__.py +1 -0
- aip_agents/ptc/mcp/templates/__init__.pyi +0 -0
- aip_agents/ptc/mcp/templates/mcp_client.py.template +239 -0
- aip_agents/ptc/naming.py +184 -0
- aip_agents/ptc/naming.pyi +76 -0
- aip_agents/ptc/payload.py +26 -0
- aip_agents/ptc/payload.pyi +15 -0
- aip_agents/ptc/prompt_builder.py +571 -0
- aip_agents/ptc/prompt_builder.pyi +55 -0
- aip_agents/ptc/ptc_helper.py +16 -0
- aip_agents/ptc/ptc_helper.pyi +1 -0
- aip_agents/ptc/sandbox_bridge.py +58 -0
- aip_agents/ptc/sandbox_bridge.pyi +25 -0
- aip_agents/ptc/template_utils.py +33 -0
- aip_agents/ptc/template_utils.pyi +13 -0
- aip_agents/ptc/templates/__init__.py +1 -0
- aip_agents/ptc/templates/__init__.pyi +0 -0
- aip_agents/ptc/templates/ptc_helper.py.template +134 -0
- aip_agents/sandbox/__init__.py +43 -0
- aip_agents/sandbox/__init__.pyi +5 -0
- aip_agents/sandbox/defaults.py +9 -0
- aip_agents/sandbox/defaults.pyi +2 -0
- aip_agents/sandbox/e2b_runtime.py +267 -0
- aip_agents/sandbox/e2b_runtime.pyi +51 -0
- aip_agents/sandbox/template_builder.py +131 -0
- aip_agents/sandbox/template_builder.pyi +36 -0
- aip_agents/sandbox/types.py +24 -0
- aip_agents/sandbox/types.pyi +14 -0
- aip_agents/sandbox/validation.py +50 -0
- aip_agents/sandbox/validation.pyi +20 -0
- aip_agents/tools/__init__.py +2 -0
- aip_agents/tools/__init__.pyi +2 -1
- aip_agents/tools/browser_use/browser_use_tool.py +8 -0
- aip_agents/tools/browser_use/streaming.py +2 -0
- aip_agents/tools/execute_ptc_code.py +305 -0
- aip_agents/tools/execute_ptc_code.pyi +87 -0
- aip_agents/utils/langgraph/tool_managers/delegation_tool_manager.py +26 -1
- aip_agents/utils/langgraph/tool_output_management.py +80 -0
- aip_agents/utils/langgraph/tool_output_management.pyi +37 -0
- {aip_agents_binary-0.5.25b9.dist-info → aip_agents_binary-0.6.1.dist-info}/METADATA +51 -48
- {aip_agents_binary-0.5.25b9.dist-info → aip_agents_binary-0.6.1.dist-info}/RECORD +73 -27
- {aip_agents_binary-0.5.25b9.dist-info → aip_agents_binary-0.6.1.dist-info}/WHEEL +0 -0
- {aip_agents_binary-0.5.25b9.dist-info → aip_agents_binary-0.6.1.dist-info}/top_level.txt +0 -0
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
from _typeshed import Incomplete
|
|
2
|
+
from aip_agents.mcp.client.base_mcp_client import BaseMCPClient as BaseMCPClient
|
|
3
|
+
from aip_agents.ptc.executor import PTCSandboxConfig as PTCSandboxConfig, PTCSandboxExecutor as PTCSandboxExecutor
|
|
4
|
+
from aip_agents.ptc.naming import sanitize_function_name as sanitize_function_name
|
|
5
|
+
from aip_agents.sandbox.e2b_runtime import E2BSandboxRuntime as E2BSandboxRuntime
|
|
6
|
+
from aip_agents.tools.tool_config_injector import TOOL_CONFIGS_KEY as TOOL_CONFIGS_KEY
|
|
7
|
+
from aip_agents.utils.logger import get_logger as get_logger
|
|
8
|
+
from langchain_core.tools import BaseTool
|
|
9
|
+
from typing import Any
|
|
10
|
+
|
|
11
|
+
logger: Incomplete
|
|
12
|
+
|
|
13
|
+
def merge_tool_configs(agent_configs: dict[str, Any] | None, runtime_configs: dict[str, Any] | None) -> dict[str, dict[str, Any]]:
|
|
14
|
+
'''Merge agent-level and runtime tool configs with sanitized keys.
|
|
15
|
+
|
|
16
|
+
Merges tool configurations from two sources:
|
|
17
|
+
1. Agent-level defaults (from agent.tool_configs)
|
|
18
|
+
2. Runtime overrides (from RunnableConfig.metadata["tool_configs"])
|
|
19
|
+
|
|
20
|
+
Both sources support two formats (matching LangGraphReactAgent behavior):
|
|
21
|
+
- Direct per-tool keys: {"time_tool": {"timezone": "UTC"}}
|
|
22
|
+
- Nested structure: {"tool_configs": {"time_tool": {"timezone": "UTC"}}}
|
|
23
|
+
|
|
24
|
+
The nested "tool_configs" key has higher precedence than direct keys.
|
|
25
|
+
Tool names are sanitized to match sandbox expectations (e.g., "Time Tool" -> "time_tool").
|
|
26
|
+
|
|
27
|
+
Args:
|
|
28
|
+
agent_configs: Agent-level tool configs (may be None or contain nested dicts)
|
|
29
|
+
runtime_configs: Runtime overrides from metadata (may be None)
|
|
30
|
+
|
|
31
|
+
Returns:
|
|
32
|
+
Merged dict with sanitized tool names as keys and config dicts as values.
|
|
33
|
+
Only includes entries that are dicts (non-dict values are agent-wide defaults).
|
|
34
|
+
'''
|
|
35
|
+
|
|
36
|
+
class PTCCodeTool(BaseTool):
|
|
37
|
+
"""Tool for executing Python code with MCP tool access in a sandbox.
|
|
38
|
+
|
|
39
|
+
This tool uses BaseTool to properly access runtime config via run_manager.metadata.
|
|
40
|
+
The config parameter is NOT exposed to the LLM schema - it's extracted from
|
|
41
|
+
the callback manager during execution.
|
|
42
|
+
"""
|
|
43
|
+
name: str
|
|
44
|
+
description: str
|
|
45
|
+
def __init__(self, executor: PTCSandboxExecutor, runtime: E2BSandboxRuntime, agent_tool_configs: dict[str, Any] | None = None, **kwargs: Any) -> None:
|
|
46
|
+
"""Initialize the PTC code tool.
|
|
47
|
+
|
|
48
|
+
Args:
|
|
49
|
+
executor: The PTC sandbox executor.
|
|
50
|
+
runtime: The E2B sandbox runtime.
|
|
51
|
+
agent_tool_configs: Optional agent-level tool configs.
|
|
52
|
+
**kwargs: Additional keyword arguments passed to BaseTool.
|
|
53
|
+
"""
|
|
54
|
+
@property
|
|
55
|
+
def args(self) -> dict[str, Any]:
|
|
56
|
+
"""Return the argument schema for the tool."""
|
|
57
|
+
async def cleanup(self) -> None:
|
|
58
|
+
"""Clean up the sandbox runtime."""
|
|
59
|
+
|
|
60
|
+
def create_execute_ptc_code_tool(mcp_client: BaseMCPClient | None, config: PTCSandboxConfig | None = None, agent_tool_configs: dict[str, Any] | None = None) -> PTCCodeTool:
|
|
61
|
+
'''Create a tool that executes Python code with MCP tool access.
|
|
62
|
+
|
|
63
|
+
The code runs inside an E2B sandbox with access to generated MCP tool modules.
|
|
64
|
+
This tool is designed for LLM-generated code that needs to call multiple tools
|
|
65
|
+
programmatically in a single execution.
|
|
66
|
+
|
|
67
|
+
Args:
|
|
68
|
+
mcp_client: The MCP client with configured servers.
|
|
69
|
+
config: Optional sandbox executor configuration.
|
|
70
|
+
agent_tool_configs: Optional agent-level tool configs (from agent.tool_configs).
|
|
71
|
+
These are merged with runtime overrides from RunnableConfig.metadata.
|
|
72
|
+
|
|
73
|
+
Returns:
|
|
74
|
+
PTCCodeTool configured for PTC code execution.
|
|
75
|
+
|
|
76
|
+
Example:
|
|
77
|
+
```python
|
|
78
|
+
from aip_agents.mcp.client import LangchainMCPClient
|
|
79
|
+
from aip_agents.tools.execute_ptc_code import create_execute_ptc_code_tool
|
|
80
|
+
|
|
81
|
+
mcp_client = LangchainMCPClient()
|
|
82
|
+
await mcp_client.add_server("yfinance", {...})
|
|
83
|
+
|
|
84
|
+
tool = create_execute_ptc_code_tool(mcp_client)
|
|
85
|
+
result = await tool.ainvoke({"code": "from tools.yfinance import get_stock\\\\nprint(get_stock(\'AAPL\'))"})
|
|
86
|
+
```
|
|
87
|
+
'''
|
|
@@ -134,7 +134,19 @@ class DelegationToolManager(BaseLangGraphToolManager):
|
|
|
134
134
|
Returns:
|
|
135
135
|
The result from the delegated agent, including artifacts if any.
|
|
136
136
|
"""
|
|
137
|
-
|
|
137
|
+
try:
|
|
138
|
+
writer: StreamWriter = get_stream_writer()
|
|
139
|
+
except Exception as exc:
|
|
140
|
+
logger.warning(
|
|
141
|
+
"DelegationToolManager: Stream writer unavailable; delegation streaming disabled.",
|
|
142
|
+
extra={"error": str(exc), "error_type": type(exc).__name__},
|
|
143
|
+
)
|
|
144
|
+
|
|
145
|
+
def _noop_writer(_: Any) -> None:
|
|
146
|
+
"""No-op writer for non-graph execution contexts."""
|
|
147
|
+
return None
|
|
148
|
+
|
|
149
|
+
writer = _noop_writer
|
|
138
150
|
|
|
139
151
|
try:
|
|
140
152
|
# Check delegation depth limit before executing
|
|
@@ -295,6 +307,19 @@ class DelegationToolManager(BaseLangGraphToolManager):
|
|
|
295
307
|
cfg_conf = cfg.get("configurable") if isinstance(cfg, dict) else None
|
|
296
308
|
if isinstance(cfg_conf, dict):
|
|
297
309
|
parent_step_id = cfg_conf.get("parent_step_id")
|
|
310
|
+
if not parent_step_id:
|
|
311
|
+
metadata = cfg.get("metadata") or {}
|
|
312
|
+
tool_call_id = (
|
|
313
|
+
cfg_conf.get("tool_call_id")
|
|
314
|
+
or metadata.get("tool_call_id")
|
|
315
|
+
or metadata.get("id")
|
|
316
|
+
or (metadata.get("tool_call") or {}).get("id")
|
|
317
|
+
)
|
|
318
|
+
if tool_call_id and self.parent_agent is not None:
|
|
319
|
+
thread_key = getattr(self.parent_agent, "thread_id_key", "thread_id")
|
|
320
|
+
thread_id = cfg_conf.get(thread_key)
|
|
321
|
+
parent_map = self.parent_agent._tool_parent_map_by_thread.get(str(thread_id), {})
|
|
322
|
+
parent_step_id = parent_map.get(str(tool_call_id))
|
|
298
323
|
_DELEGATION_PARENT_STEP_ID_CVAR.set(parent_step_id)
|
|
299
324
|
except Exception:
|
|
300
325
|
_DELEGATION_PARENT_STEP_ID_CVAR.set(None)
|
|
@@ -471,6 +471,86 @@ class ToolOutputManager:
|
|
|
471
471
|
"""
|
|
472
472
|
return self._generate_json_summary(thread_id, max_entries)
|
|
473
473
|
|
|
474
|
+
def get_latest_reference(self, thread_id: str) -> str | None:
|
|
475
|
+
"""Return the most recent tool output reference for a thread.
|
|
476
|
+
|
|
477
|
+
Args:
|
|
478
|
+
thread_id: Thread ID to retrieve the latest output reference for.
|
|
479
|
+
|
|
480
|
+
Returns:
|
|
481
|
+
Latest tool output reference string or None when unavailable.
|
|
482
|
+
"""
|
|
483
|
+
try:
|
|
484
|
+
summary = json.loads(self.generate_summary(thread_id, max_entries=1))
|
|
485
|
+
except Exception as exc:
|
|
486
|
+
logger.debug("Failed to parse tool output summary: %s", exc)
|
|
487
|
+
return None
|
|
488
|
+
|
|
489
|
+
if not summary:
|
|
490
|
+
return None
|
|
491
|
+
latest = summary[0].get("reference")
|
|
492
|
+
return latest if isinstance(latest, str) and latest else None
|
|
493
|
+
|
|
494
|
+
def has_reference(self, value: Any) -> bool:
|
|
495
|
+
"""Check whether a value contains a tool output reference.
|
|
496
|
+
|
|
497
|
+
Args:
|
|
498
|
+
value: Value to inspect for tool output references.
|
|
499
|
+
|
|
500
|
+
Returns:
|
|
501
|
+
True if any tool output reference is present.
|
|
502
|
+
"""
|
|
503
|
+
if isinstance(value, str):
|
|
504
|
+
return value.startswith(TOOL_OUTPUT_REFERENCE_PREFIX)
|
|
505
|
+
if isinstance(value, dict):
|
|
506
|
+
return any(self.has_reference(item) for item in value.values())
|
|
507
|
+
if isinstance(value, list):
|
|
508
|
+
return any(self.has_reference(item) for item in value)
|
|
509
|
+
return False
|
|
510
|
+
|
|
511
|
+
def should_replace_with_reference(self, value: Any) -> bool:
|
|
512
|
+
"""Check whether a tool argument value should use a tool output reference.
|
|
513
|
+
|
|
514
|
+
Args:
|
|
515
|
+
value: Value to evaluate for replacement.
|
|
516
|
+
|
|
517
|
+
Returns:
|
|
518
|
+
True if the value should be replaced with a reference.
|
|
519
|
+
"""
|
|
520
|
+
if isinstance(value, dict | list | tuple):
|
|
521
|
+
return True
|
|
522
|
+
if isinstance(value, str):
|
|
523
|
+
return len(value) > DATA_PREVIEW_TRUNCATION_LENGTH
|
|
524
|
+
return False
|
|
525
|
+
|
|
526
|
+
def rewrite_args_with_latest_reference(self, args: dict[str, Any], thread_id: str) -> dict[str, Any]:
|
|
527
|
+
"""Rewrite tool args to use the latest tool output reference when appropriate.
|
|
528
|
+
|
|
529
|
+
Args:
|
|
530
|
+
args: Tool arguments to rewrite.
|
|
531
|
+
thread_id: Thread ID used for resolving stored outputs.
|
|
532
|
+
|
|
533
|
+
Returns:
|
|
534
|
+
Updated args dictionary with references substituted when needed.
|
|
535
|
+
"""
|
|
536
|
+
if not self.has_outputs(thread_id):
|
|
537
|
+
return args
|
|
538
|
+
if self.has_reference(args):
|
|
539
|
+
return args
|
|
540
|
+
|
|
541
|
+
latest_reference = self.get_latest_reference(thread_id)
|
|
542
|
+
if not latest_reference:
|
|
543
|
+
return args
|
|
544
|
+
|
|
545
|
+
updated_args = dict(args)
|
|
546
|
+
replaced_any = False
|
|
547
|
+
for key, value in args.items():
|
|
548
|
+
if self.should_replace_with_reference(value):
|
|
549
|
+
updated_args[key] = latest_reference
|
|
550
|
+
replaced_any = True
|
|
551
|
+
|
|
552
|
+
return updated_args if replaced_any else args
|
|
553
|
+
|
|
474
554
|
def _generate_json_summary(self, thread_id: str, max_entries: int) -> str:
|
|
475
555
|
"""Generate simplified JSON summary optimized for LLM prompts.
|
|
476
556
|
|
|
@@ -232,6 +232,43 @@ class ToolOutputManager:
|
|
|
232
232
|
A JSON string containing structured data about tool outputs. Always returns
|
|
233
233
|
valid JSON, even when no outputs are stored (empty entries list).
|
|
234
234
|
"""
|
|
235
|
+
def get_latest_reference(self, thread_id: str) -> str | None:
|
|
236
|
+
"""Return the most recent tool output reference for a thread.
|
|
237
|
+
|
|
238
|
+
Args:
|
|
239
|
+
thread_id: Thread ID to retrieve the latest output reference for.
|
|
240
|
+
|
|
241
|
+
Returns:
|
|
242
|
+
Latest tool output reference string or None when unavailable.
|
|
243
|
+
"""
|
|
244
|
+
def has_reference(self, value: Any) -> bool:
|
|
245
|
+
"""Check whether a value contains a tool output reference.
|
|
246
|
+
|
|
247
|
+
Args:
|
|
248
|
+
value: Value to inspect for tool output references.
|
|
249
|
+
|
|
250
|
+
Returns:
|
|
251
|
+
True if any tool output reference is present.
|
|
252
|
+
"""
|
|
253
|
+
def should_replace_with_reference(self, value: Any) -> bool:
|
|
254
|
+
"""Check whether a tool argument value should use a tool output reference.
|
|
255
|
+
|
|
256
|
+
Args:
|
|
257
|
+
value: Value to evaluate for replacement.
|
|
258
|
+
|
|
259
|
+
Returns:
|
|
260
|
+
True if the value should be replaced with a reference.
|
|
261
|
+
"""
|
|
262
|
+
def rewrite_args_with_latest_reference(self, args: dict[str, Any], thread_id: str) -> dict[str, Any]:
|
|
263
|
+
"""Rewrite tool args to use the latest tool output reference when appropriate.
|
|
264
|
+
|
|
265
|
+
Args:
|
|
266
|
+
args: Tool arguments to rewrite.
|
|
267
|
+
thread_id: Thread ID used for resolving stored outputs.
|
|
268
|
+
|
|
269
|
+
Returns:
|
|
270
|
+
Updated args dictionary with references substituted when needed.
|
|
271
|
+
"""
|
|
235
272
|
def clear_all(self) -> None:
|
|
236
273
|
"""Clear all stored outputs from both metadata and storage.
|
|
237
274
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: aip-agents-binary
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.6.1
|
|
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
|
|
@@ -21,22 +21,12 @@ Requires-Dist: langchain<0.4.0,>=0.3.0
|
|
|
21
21
|
Requires-Dist: langchain-openai<0.4.0,>=0.3.17
|
|
22
22
|
Requires-Dist: langchain-mcp-adapters<0.1.0,>=0.0.10
|
|
23
23
|
Requires-Dist: langchain-experimental<0.4.0,>=0.3.4
|
|
24
|
-
Requires-Dist: langgraph<0.
|
|
24
|
+
Requires-Dist: langgraph<0.7.0,>=0.6.0
|
|
25
25
|
Requires-Dist: minio<8.0.0,>=7.2.20
|
|
26
26
|
Requires-Dist: pydantic<3.0.0,>=2.11.7
|
|
27
27
|
Requires-Dist: python-dotenv<2.0.0,>=1.1.0
|
|
28
28
|
Requires-Dist: requests<3.0.0,>=2.32.4
|
|
29
29
|
Requires-Dist: uvicorn<0.35.0,>=0.34.3
|
|
30
|
-
Provides-Extra: dev
|
|
31
|
-
Requires-Dist: coverage<8.0.0,>=7.4.4; extra == "dev"
|
|
32
|
-
Requires-Dist: mypy<2.0.0,>=1.15.0; extra == "dev"
|
|
33
|
-
Requires-Dist: pre-commit<4.0.0,>=3.7.0; extra == "dev"
|
|
34
|
-
Requires-Dist: pytest<9.0.0,>=8.1.1; extra == "dev"
|
|
35
|
-
Requires-Dist: pytest-asyncio<0.24.0,>=0.23.6; extra == "dev"
|
|
36
|
-
Requires-Dist: pytest-cov<6.0.0,>=5.0.0; extra == "dev"
|
|
37
|
-
Requires-Dist: pytest-xdist>=3.8.0; extra == "dev"
|
|
38
|
-
Requires-Dist: ruff<0.7.0,>=0.6.7; extra == "dev"
|
|
39
|
-
Requires-Dist: pillow<12.0.0,>=11.3.0; extra == "dev"
|
|
40
30
|
Provides-Extra: memory
|
|
41
31
|
Requires-Dist: gllm-memory-binary[mem0ai]<0.2.0,>=0.1.1; extra == "memory"
|
|
42
32
|
Provides-Extra: privacy
|
|
@@ -55,6 +45,17 @@ Requires-Dist: unidecode<2.0.0,>=1.3.0; extra == "local"
|
|
|
55
45
|
Requires-Dist: gllm-docproc-binary[docx,pdf,xlsx]<0.8.0,>=0.7.21; extra == "local"
|
|
56
46
|
Requires-Dist: gllm-multimodal-binary==0.2.0.post1; extra == "local"
|
|
57
47
|
Requires-Dist: bosa-connectors-binary<0.4.0,>=0.3.1; extra == "local"
|
|
48
|
+
Provides-Extra: dev
|
|
49
|
+
Requires-Dist: coverage<8.0.0,>=7.4.4; extra == "dev"
|
|
50
|
+
Requires-Dist: mypy<2.0.0,>=1.15.0; extra == "dev"
|
|
51
|
+
Requires-Dist: nest-asyncio<2.0.0,>=1.6.0; extra == "dev"
|
|
52
|
+
Requires-Dist: pre-commit<4.0.0,>=3.7.0; extra == "dev"
|
|
53
|
+
Requires-Dist: pytest<9.0.0,>=8.1.1; extra == "dev"
|
|
54
|
+
Requires-Dist: pytest-asyncio<0.24.0,>=0.23.6; extra == "dev"
|
|
55
|
+
Requires-Dist: pytest-cov<6.0.0,>=5.0.0; extra == "dev"
|
|
56
|
+
Requires-Dist: pytest-xdist>=3.8.0; extra == "dev"
|
|
57
|
+
Requires-Dist: ruff<0.7.0,>=0.6.7; extra == "dev"
|
|
58
|
+
Requires-Dist: pillow<12.0.0,>=11.3.0; extra == "dev"
|
|
58
59
|
|
|
59
60
|
# AIP Agents
|
|
60
61
|
|
|
@@ -73,13 +74,13 @@ You can use `aip-agents` directly for local execution, or let `glaip-sdk` manage
|
|
|
73
74
|
### Prerequisites
|
|
74
75
|
- Python 3.11 - 3.12 - [Install here](https://www.python.org/downloads/)
|
|
75
76
|
- Pip (if using Pip) - [Install here](https://pip.pypa.io/en/stable/installation/)
|
|
76
|
-
-
|
|
77
|
+
- Poetry 1.8.1+ (if using Poetry) - [Install here](https://python-poetry.org/docs/#installation)
|
|
77
78
|
- Git (if using Git) - [Install here](https://git-scm.com/downloads)
|
|
78
79
|
- For git installation:
|
|
79
80
|
- Access to the [GDP Labs SDK repository](https://github.com/GDP-ADMIN/glaip-sdk)
|
|
80
81
|
|
|
81
82
|
### 1. Installation from the GDP Labs registry
|
|
82
|
-
This package is published to the internal GDP Labs registry. Ensure your
|
|
83
|
+
This package is published to the internal GDP Labs registry. Ensure your pip/Poetry config includes the registry:
|
|
83
84
|
`https://glsdk.gdplabs.id/gen-ai-internal/simple/`.
|
|
84
85
|
|
|
85
86
|
#### Using pip
|
|
@@ -87,15 +88,15 @@ This package is published to the internal GDP Labs registry. Ensure your uv/pip
|
|
|
87
88
|
pip install aip-agents
|
|
88
89
|
```
|
|
89
90
|
|
|
90
|
-
#### Using
|
|
91
|
+
#### Using Poetry
|
|
91
92
|
```bash
|
|
92
|
-
|
|
93
|
+
poetry add aip-agents
|
|
93
94
|
```
|
|
94
95
|
|
|
95
96
|
### 2. Development Installation (Git)
|
|
96
97
|
For development purposes, you can install directly from the Git repository:
|
|
97
98
|
```bash
|
|
98
|
-
|
|
99
|
+
poetry add "git+ssh://git@github.com/GDP-ADMIN/glaip-sdk.git#subdirectory=python/aip-agents"
|
|
99
100
|
```
|
|
100
101
|
|
|
101
102
|
### 3. Recommended: install via glaip-sdk for local mode
|
|
@@ -112,19 +113,21 @@ pip install "aip-agents[privacy]"
|
|
|
112
113
|
|
|
113
114
|
## Managing Dependencies
|
|
114
115
|
1. Go to the `aip-agents` module root, e.g. `cd python/aip-agents`.
|
|
115
|
-
2. Run `
|
|
116
|
-
3. Run `
|
|
116
|
+
2. Run `poetry shell` to create a virtual environment.
|
|
117
|
+
3. Run `poetry install` to install the `aip-agents` requirements (Poetry will generate a local lock file for you if needed; the repository ignores it).
|
|
118
|
+
4. Run `poetry update` if you change any dependency versions in `pyproject.toml`.
|
|
117
119
|
|
|
118
120
|
## Contributing
|
|
119
121
|
Please refer to this [Python Style Guide](https://docs.google.com/document/d/1uRggCrHnVfDPBnG641FyQBwUwLoFw0kTzNqRm92vUwM/edit?usp=sharing)
|
|
120
122
|
to get information about code style, documentation standard, and SCA that you need to use when contributing to this project
|
|
121
123
|
|
|
122
124
|
1. Activate `pre-commit` hooks using `pre-commit install`
|
|
123
|
-
2. Run `
|
|
124
|
-
3. Run `
|
|
125
|
-
4.
|
|
125
|
+
2. Run `poetry shell` to create a virtual environment.
|
|
126
|
+
3. Run `poetry install` to install the `aip-agents` requirements (this will also create a local lock file that stays local).
|
|
127
|
+
4. Run `which python` to get the path to be referenced at Visual Studio Code interpreter path (`Ctrl`+`Shift`+`P` or `Cmd`+`Shift`+`P`)
|
|
128
|
+
5. Try running the unit test to see if it's working:
|
|
126
129
|
```bash
|
|
127
|
-
|
|
130
|
+
poetry run pytest -s tests/unit_tests/
|
|
128
131
|
```
|
|
129
132
|
|
|
130
133
|
## Hello World Examples
|
|
@@ -225,57 +228,57 @@ For STDIO, SSE, and HTTP transports using local servers, open a terminal in the
|
|
|
225
228
|
- For STDIO:
|
|
226
229
|
|
|
227
230
|
```bash
|
|
228
|
-
|
|
231
|
+
poetry run python aip_agents/examples/mcp_servers/mcp_server_stdio.py
|
|
229
232
|
```
|
|
230
233
|
|
|
231
234
|
- For SSE:
|
|
232
235
|
|
|
233
236
|
```bash
|
|
234
|
-
|
|
237
|
+
poetry run python aip_agents/examples/mcp_servers/mcp_server_sse.py
|
|
235
238
|
```
|
|
236
239
|
|
|
237
240
|
- For HTTP:
|
|
238
241
|
|
|
239
242
|
```bash
|
|
240
|
-
|
|
243
|
+
poetry run python aip_agents/examples/mcp_servers/mcp_server_http.py
|
|
241
244
|
```
|
|
242
245
|
|
|
243
246
|
Note: Start the appropriate server before running the client examples for that transport.
|
|
244
247
|
|
|
245
248
|
### Running Examples
|
|
246
249
|
|
|
247
|
-
All examples are run from the library root using `
|
|
250
|
+
All examples are run from the library root using `poetry run python aip_agents/examples/<file>.py`. Examples support OpenAI for LangGraph/LangChain and Google ADK where specified.
|
|
248
251
|
|
|
249
252
|
#### LangChain Examples
|
|
250
253
|
|
|
251
254
|
##### STDIO Transport
|
|
252
255
|
- Non-Streaming:
|
|
253
256
|
```bash
|
|
254
|
-
|
|
257
|
+
poetry run python aip_agents/examples/hello_world_langchain_mcp_stdio.py
|
|
255
258
|
```
|
|
256
259
|
- Streaming:
|
|
257
260
|
```bash
|
|
258
|
-
|
|
261
|
+
poetry run python aip_agents/examples/hello_world_langchain_mcp_stdio_stream.py
|
|
259
262
|
```
|
|
260
263
|
|
|
261
264
|
##### SSE Transport
|
|
262
265
|
- Non-Streaming:
|
|
263
266
|
```bash
|
|
264
|
-
|
|
267
|
+
poetry run python aip_agents/examples/hello_world_langchain_mcp_sse.py
|
|
265
268
|
```
|
|
266
269
|
- Streaming:
|
|
267
270
|
```bash
|
|
268
|
-
|
|
271
|
+
poetry run python aip_agents/examples/hello_world_langchain_mcp_sse_stream.py
|
|
269
272
|
```
|
|
270
273
|
|
|
271
274
|
##### HTTP Transport
|
|
272
275
|
- Non-Streaming:
|
|
273
276
|
```bash
|
|
274
|
-
|
|
277
|
+
poetry run python aip_agents/examples/hello_world_langchain_mcp_http.py
|
|
275
278
|
```
|
|
276
279
|
- Streaming:
|
|
277
280
|
```bash
|
|
278
|
-
|
|
281
|
+
poetry run python aip_agents/examples/hello_world_langchain_mcp_http_stream.py
|
|
279
282
|
```
|
|
280
283
|
|
|
281
284
|
#### Google ADK Examples
|
|
@@ -283,31 +286,31 @@ uv run python aip_agents/examples/hello_world_langchain_mcp_http_stream.py
|
|
|
283
286
|
##### STDIO Transport
|
|
284
287
|
- Non-Streaming:
|
|
285
288
|
```bash
|
|
286
|
-
|
|
289
|
+
poetry run python aip_agents/examples/hello_world_google_adk_mcp_stdio.py
|
|
287
290
|
```
|
|
288
291
|
- Streaming:
|
|
289
292
|
```bash
|
|
290
|
-
|
|
293
|
+
poetry run python aip_agents/examples/hello_world_google_adk_mcp_stdio_stream.py
|
|
291
294
|
```
|
|
292
295
|
|
|
293
296
|
##### SSE Transport
|
|
294
297
|
- Non-Streaming:
|
|
295
298
|
```bash
|
|
296
|
-
|
|
299
|
+
poetry run python aip_agents/examples/hello_world_google_adk_mcp_sse.py
|
|
297
300
|
```
|
|
298
301
|
- Streaming:
|
|
299
302
|
```bash
|
|
300
|
-
|
|
303
|
+
poetry run python aip_agents/examples/hello_world_google_adk_mcp_sse_stream.py
|
|
301
304
|
```
|
|
302
305
|
|
|
303
306
|
##### HTTP Transport
|
|
304
307
|
- Non-Streaming:
|
|
305
308
|
```bash
|
|
306
|
-
|
|
309
|
+
poetry run python aip_agents/examples/hello_world_google_adk_mcp_http.py
|
|
307
310
|
```
|
|
308
311
|
- Streaming:
|
|
309
312
|
```bash
|
|
310
|
-
|
|
313
|
+
poetry run python aip_agents/examples/hello_world_google_adk_mcp_http_stream.py
|
|
311
314
|
```
|
|
312
315
|
|
|
313
316
|
#### LangGraph Examples (OpenAI)
|
|
@@ -315,31 +318,31 @@ uv run python aip_agents/examples/hello_world_google_adk_mcp_http_stream.py
|
|
|
315
318
|
##### STDIO Transport
|
|
316
319
|
- Non-Streaming:
|
|
317
320
|
```bash
|
|
318
|
-
|
|
321
|
+
poetry run python aip_agents/examples/hello_world_langgraph_mcp_stdio.py
|
|
319
322
|
```
|
|
320
323
|
- Streaming:
|
|
321
324
|
```bash
|
|
322
|
-
|
|
325
|
+
poetry run python aip_agents/examples/hello_world_langgraph_mcp_stdio_stream.py
|
|
323
326
|
```
|
|
324
327
|
|
|
325
328
|
##### SSE Transport
|
|
326
329
|
- Non-Streaming:
|
|
327
330
|
```bash
|
|
328
|
-
|
|
331
|
+
poetry run python aip_agents/examples/hello_world_langgraph_mcp_sse.py
|
|
329
332
|
```
|
|
330
333
|
- Streaming:
|
|
331
334
|
```bash
|
|
332
|
-
|
|
335
|
+
poetry run python aip_agents/examples/hello_world_langgraph_mcp_sse_stream.py
|
|
333
336
|
```
|
|
334
337
|
|
|
335
338
|
##### HTTP Transport
|
|
336
339
|
- Non-Streaming:
|
|
337
340
|
```bash
|
|
338
|
-
|
|
341
|
+
poetry run python aip_agents/examples/hello_world_langgraph_mcp_http.py
|
|
339
342
|
```
|
|
340
343
|
- Streaming:
|
|
341
344
|
```bash
|
|
342
|
-
|
|
345
|
+
poetry run python aip_agents/examples/hello_world_langgraph_mcp_http_stream.py
|
|
343
346
|
```
|
|
344
347
|
|
|
345
348
|
### Multi-Server Example
|
|
@@ -355,13 +358,13 @@ npx @playwright/mcp@latest --headless --port 8931
|
|
|
355
358
|
2. In another terminal, start the Name Generator SSE server:
|
|
356
359
|
|
|
357
360
|
```bash
|
|
358
|
-
|
|
361
|
+
poetry run python aip_agents/examples/mcp_servers/mcp_name.py
|
|
359
362
|
```
|
|
360
363
|
|
|
361
364
|
3. Run the multi-server client example:
|
|
362
365
|
|
|
363
366
|
```bash
|
|
364
|
-
|
|
367
|
+
poetry run python aip_agents/examples/hello_world_langchain_mcp_multi_server.py
|
|
365
368
|
```
|
|
366
369
|
**3. Running Individual A2A Examples:**
|
|
367
370
|
|
|
@@ -477,7 +480,7 @@ The library supports Mem0 as a memory backend for long-term conversation recall.
|
|
|
477
480
|
Use the coordinator example with memory enabled:
|
|
478
481
|
|
|
479
482
|
```bash
|
|
480
|
-
|
|
483
|
+
poetry run python aip_agents/examples/hello_world_a2a_mem0_coordinator_server.py
|
|
481
484
|
```
|
|
482
485
|
|
|
483
486
|
In client:
|