aip-agents-binary 0.5.21__py3-none-macosx_13_0_arm64.whl → 0.6.8__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.
- aip_agents/agent/__init__.py +44 -4
- aip_agents/agent/base_langgraph_agent.py +169 -74
- aip_agents/agent/base_langgraph_agent.pyi +3 -2
- aip_agents/agent/langgraph_memory_enhancer_agent.py +368 -34
- aip_agents/agent/langgraph_memory_enhancer_agent.pyi +3 -2
- aip_agents/agent/langgraph_react_agent.py +424 -35
- aip_agents/agent/langgraph_react_agent.pyi +46 -2
- aip_agents/examples/{hello_world_langgraph_bosa_twitter.py → hello_world_langgraph_gl_connector_twitter.py} +10 -7
- aip_agents/examples/hello_world_langgraph_gl_connector_twitter.pyi +5 -0
- aip_agents/examples/hello_world_ptc.py +49 -0
- aip_agents/examples/hello_world_ptc.pyi +5 -0
- aip_agents/examples/hello_world_ptc_custom_tools.py +83 -0
- aip_agents/examples/hello_world_ptc_custom_tools.pyi +7 -0
- aip_agents/examples/hello_world_sentry.py +2 -2
- aip_agents/examples/hello_world_tool_output_client.py +9 -0
- aip_agents/examples/tools/multiply_tool.py +43 -0
- aip_agents/examples/tools/multiply_tool.pyi +18 -0
- aip_agents/guardrails/__init__.py +83 -0
- aip_agents/guardrails/__init__.pyi +6 -0
- aip_agents/guardrails/engines/__init__.py +69 -0
- aip_agents/guardrails/engines/__init__.pyi +4 -0
- aip_agents/guardrails/engines/base.py +90 -0
- aip_agents/guardrails/engines/base.pyi +61 -0
- aip_agents/guardrails/engines/nemo.py +101 -0
- aip_agents/guardrails/engines/nemo.pyi +46 -0
- aip_agents/guardrails/engines/phrase_matcher.py +113 -0
- aip_agents/guardrails/engines/phrase_matcher.pyi +48 -0
- aip_agents/guardrails/exceptions.py +39 -0
- aip_agents/guardrails/exceptions.pyi +23 -0
- aip_agents/guardrails/manager.py +163 -0
- aip_agents/guardrails/manager.pyi +42 -0
- aip_agents/guardrails/middleware.py +199 -0
- aip_agents/guardrails/middleware.pyi +87 -0
- aip_agents/guardrails/schemas.py +63 -0
- aip_agents/guardrails/schemas.pyi +43 -0
- aip_agents/guardrails/utils.py +45 -0
- aip_agents/guardrails/utils.pyi +19 -0
- aip_agents/mcp/client/__init__.py +38 -2
- 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 -65
- aip_agents/mcp/client/persistent_session.pyi +9 -0
- aip_agents/mcp/client/transports.py +52 -4
- aip_agents/mcp/client/transports.pyi +9 -0
- aip_agents/memory/adapters/base_adapter.py +98 -0
- aip_agents/memory/adapters/base_adapter.pyi +25 -0
- aip_agents/middleware/base.py +8 -0
- aip_agents/middleware/base.pyi +4 -0
- aip_agents/middleware/manager.py +22 -0
- aip_agents/middleware/manager.pyi +4 -0
- aip_agents/ptc/__init__.py +87 -0
- aip_agents/ptc/__init__.pyi +14 -0
- aip_agents/ptc/custom_tools.py +473 -0
- aip_agents/ptc/custom_tools.pyi +184 -0
- aip_agents/ptc/custom_tools_payload.py +400 -0
- aip_agents/ptc/custom_tools_payload.pyi +31 -0
- aip_agents/ptc/custom_tools_templates/__init__.py +1 -0
- aip_agents/ptc/custom_tools_templates/__init__.pyi +0 -0
- aip_agents/ptc/custom_tools_templates/custom_build_function.py.template +23 -0
- aip_agents/ptc/custom_tools_templates/custom_init.py.template +15 -0
- aip_agents/ptc/custom_tools_templates/custom_invoke.py.template +60 -0
- aip_agents/ptc/custom_tools_templates/custom_registry.py.template +87 -0
- aip_agents/ptc/custom_tools_templates/custom_sources_init.py.template +7 -0
- aip_agents/ptc/custom_tools_templates/custom_wrapper.py.template +19 -0
- aip_agents/ptc/doc_gen.py +122 -0
- aip_agents/ptc/doc_gen.pyi +40 -0
- aip_agents/ptc/exceptions.py +57 -0
- aip_agents/ptc/exceptions.pyi +37 -0
- aip_agents/ptc/executor.py +261 -0
- aip_agents/ptc/executor.pyi +99 -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 +196 -0
- aip_agents/ptc/naming.pyi +85 -0
- aip_agents/ptc/payload.py +26 -0
- aip_agents/ptc/payload.pyi +15 -0
- aip_agents/ptc/prompt_builder.py +673 -0
- aip_agents/ptc/prompt_builder.pyi +59 -0
- aip_agents/ptc/ptc_helper.py +16 -0
- aip_agents/ptc/ptc_helper.pyi +1 -0
- aip_agents/ptc/sandbox_bridge.py +256 -0
- aip_agents/ptc/sandbox_bridge.pyi +38 -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/ptc/tool_def_helpers.py +101 -0
- aip_agents/ptc/tool_def_helpers.pyi +38 -0
- aip_agents/ptc/tool_enrichment.py +163 -0
- aip_agents/ptc/tool_enrichment.pyi +60 -0
- aip_agents/sandbox/__init__.py +43 -0
- aip_agents/sandbox/__init__.pyi +5 -0
- aip_agents/sandbox/defaults.py +205 -0
- aip_agents/sandbox/defaults.pyi +30 -0
- aip_agents/sandbox/e2b_runtime.py +295 -0
- aip_agents/sandbox/e2b_runtime.pyi +57 -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/sentry/__init__.py +1 -1
- aip_agents/sentry/sentry.py +33 -12
- aip_agents/sentry/sentry.pyi +5 -4
- aip_agents/tools/__init__.py +20 -3
- aip_agents/tools/__init__.pyi +4 -2
- aip_agents/tools/browser_use/browser_use_tool.py +8 -0
- aip_agents/tools/browser_use/streaming.py +2 -0
- aip_agents/tools/code_sandbox/e2b_cloud_sandbox_extended.py +80 -31
- aip_agents/tools/code_sandbox/e2b_cloud_sandbox_extended.pyi +25 -9
- aip_agents/tools/code_sandbox/e2b_sandbox_tool.py +6 -6
- aip_agents/tools/constants.py +24 -12
- aip_agents/tools/constants.pyi +14 -11
- aip_agents/tools/date_range_tool.py +554 -0
- aip_agents/tools/date_range_tool.pyi +21 -0
- aip_agents/tools/execute_ptc_code.py +357 -0
- aip_agents/tools/execute_ptc_code.pyi +90 -0
- aip_agents/tools/gl_connector/__init__.py +1 -1
- aip_agents/tools/gl_connector/tool.py +62 -30
- aip_agents/tools/gl_connector/tool.pyi +3 -3
- aip_agents/tools/gl_connector_tools.py +119 -0
- aip_agents/tools/gl_connector_tools.pyi +39 -0
- aip_agents/tools/memory_search/__init__.py +8 -1
- aip_agents/tools/memory_search/__init__.pyi +3 -3
- aip_agents/tools/memory_search/mem0.py +114 -1
- aip_agents/tools/memory_search/mem0.pyi +11 -1
- aip_agents/tools/memory_search/schema.py +33 -0
- aip_agents/tools/memory_search/schema.pyi +10 -0
- aip_agents/tools/memory_search_tool.py +8 -0
- aip_agents/tools/memory_search_tool.pyi +2 -2
- 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.21.dist-info → aip_agents_binary-0.6.8.dist-info}/METADATA +14 -22
- {aip_agents_binary-0.5.21.dist-info → aip_agents_binary-0.6.8.dist-info}/RECORD +144 -58
- {aip_agents_binary-0.5.21.dist-info → aip_agents_binary-0.6.8.dist-info}/WHEEL +1 -1
- aip_agents/examples/demo_memory_recall.py +0 -401
- aip_agents/examples/demo_memory_recall.pyi +0 -58
- aip_agents/examples/hello_world_langgraph_bosa_twitter.pyi +0 -5
- aip_agents/tools/bosa_tools.py +0 -105
- aip_agents/tools/bosa_tools.pyi +0 -37
- {aip_agents_binary-0.5.21.dist-info → aip_agents_binary-0.6.8.dist-info}/top_level.txt +0 -0
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
"""Auto-generated tools from GL Connectors.
|
|
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 (
|
|
11
|
+
GL_CONNECTORS_API_KEY,
|
|
12
|
+
GL_CONNECTORS_BASE_URL,
|
|
13
|
+
GL_CONNECTORS_FETCH_MAX_RETRIES,
|
|
14
|
+
ToolType,
|
|
15
|
+
)
|
|
16
|
+
from aip_agents.utils.logger import get_logger
|
|
17
|
+
|
|
18
|
+
logger = get_logger(__name__)
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
def get_gl_connector_modules_with_retry() -> list[str]:
|
|
22
|
+
"""Try to get available modules with retries.
|
|
23
|
+
|
|
24
|
+
Returns:
|
|
25
|
+
List of available modules.
|
|
26
|
+
"""
|
|
27
|
+
if not GL_CONNECTORS_BASE_URL or not GL_CONNECTORS_API_KEY:
|
|
28
|
+
logger.warning("GL Connectors credentials missing (base_url or api_key); returning empty modules list")
|
|
29
|
+
return []
|
|
30
|
+
|
|
31
|
+
connector = BosaConnector(api_base_url=GL_CONNECTORS_BASE_URL, api_key=GL_CONNECTORS_API_KEY)
|
|
32
|
+
modules = []
|
|
33
|
+
for attempt in range(GL_CONNECTORS_FETCH_MAX_RETRIES):
|
|
34
|
+
try:
|
|
35
|
+
modules = list(connector.get_available_modules())
|
|
36
|
+
if modules:
|
|
37
|
+
return modules
|
|
38
|
+
logger.warning(
|
|
39
|
+
f"Failed to get GL Connectors available modules, retrying... (attempt {attempt + 1} / {GL_CONNECTORS_FETCH_MAX_RETRIES})"
|
|
40
|
+
)
|
|
41
|
+
except Exception as e:
|
|
42
|
+
logger.exception(
|
|
43
|
+
f"Exception when getting GL Connectors available modules (attempt {attempt + 1} / {GL_CONNECTORS_FETCH_MAX_RETRIES}): {e}"
|
|
44
|
+
)
|
|
45
|
+
logger.error("Failed to get GL Connectors available modules after maximum retries")
|
|
46
|
+
return modules
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
class LazyGLConnectorToolsDict(dict):
|
|
50
|
+
"""Lazy dictionary for GL Connectors."""
|
|
51
|
+
|
|
52
|
+
def __missing__(self, app):
|
|
53
|
+
"""When a key is missing, create the tools and store them in the dictionary.
|
|
54
|
+
|
|
55
|
+
Args:
|
|
56
|
+
app: Name of the GL Connectors.
|
|
57
|
+
|
|
58
|
+
Returns:
|
|
59
|
+
List of tools generated by the GL Connectors tool generator.
|
|
60
|
+
"""
|
|
61
|
+
if app not in get_gl_connector_modules():
|
|
62
|
+
return []
|
|
63
|
+
tools = []
|
|
64
|
+
for attempt in range(GL_CONNECTORS_FETCH_MAX_RETRIES):
|
|
65
|
+
try:
|
|
66
|
+
tools = BOSAConnectorToolGenerator(
|
|
67
|
+
api_base_url=GL_CONNECTORS_BASE_URL,
|
|
68
|
+
api_key=GL_CONNECTORS_API_KEY,
|
|
69
|
+
app_name=app,
|
|
70
|
+
).generate_tools(tool_type=ToolType.LANGCHAIN)
|
|
71
|
+
if tools:
|
|
72
|
+
self[app] = tools
|
|
73
|
+
return tools
|
|
74
|
+
logger.warning(
|
|
75
|
+
f"Failed to create GL Connectors, retrying... (attempt {attempt + 1} / {GL_CONNECTORS_FETCH_MAX_RETRIES})"
|
|
76
|
+
)
|
|
77
|
+
except Exception as e:
|
|
78
|
+
logger.exception(
|
|
79
|
+
f"Exception when creating GL Connectors for app '{app}' "
|
|
80
|
+
f"(attempt {attempt + 1} / {GL_CONNECTORS_FETCH_MAX_RETRIES}): {e}"
|
|
81
|
+
)
|
|
82
|
+
logger.error("Failed to create GL Connectors after maximum retries")
|
|
83
|
+
return tools
|
|
84
|
+
|
|
85
|
+
|
|
86
|
+
# Supported modules (dynamic)
|
|
87
|
+
def get_gl_connector_modules() -> list[str]:
|
|
88
|
+
"""Lazily fetch and cache GL Connectors modules.
|
|
89
|
+
|
|
90
|
+
Returns:
|
|
91
|
+
List of GL Connectors modules.
|
|
92
|
+
"""
|
|
93
|
+
if not hasattr(get_gl_connector_modules, "_cache"):
|
|
94
|
+
get_gl_connector_modules._cache = get_gl_connector_modules_with_retry()
|
|
95
|
+
return get_gl_connector_modules._cache
|
|
96
|
+
|
|
97
|
+
|
|
98
|
+
# FOR BACKWARDS COMPATIBILITY
|
|
99
|
+
def get_bosa_modules() -> list[str]:
|
|
100
|
+
"""Backward-compatible alias for get_gl_connector_modules."""
|
|
101
|
+
return get_gl_connector_modules()
|
|
102
|
+
|
|
103
|
+
|
|
104
|
+
GL_CONNECTORS_MODULES = [
|
|
105
|
+
"github",
|
|
106
|
+
"twitter",
|
|
107
|
+
"google",
|
|
108
|
+
"google_drive",
|
|
109
|
+
"google_mail",
|
|
110
|
+
"google_docs",
|
|
111
|
+
]
|
|
112
|
+
|
|
113
|
+
# FOR BACKWARDS COMPATIBILITY
|
|
114
|
+
BOSA_MODULES = GL_CONNECTORS_MODULES
|
|
115
|
+
|
|
116
|
+
GL_CONNECTORS_AUTOMATED_TOOLS: dict[str, list[BaseTool]] = LazyGLConnectorToolsDict()
|
|
117
|
+
|
|
118
|
+
# FOR BACKWARDS COMPATIBILITY
|
|
119
|
+
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
|
|
@@ -6,17 +6,24 @@ Authors:
|
|
|
6
6
|
|
|
7
7
|
from aip_agents.tools.memory_search.base import LongTermMemorySearchTool
|
|
8
8
|
from aip_agents.tools.memory_search.mem0 import (
|
|
9
|
+
MEMORY_DELETE_TOOL_NAME,
|
|
9
10
|
MEMORY_SEARCH_TOOL_NAME,
|
|
11
|
+
Mem0DeleteInput,
|
|
12
|
+
Mem0DeleteTool,
|
|
10
13
|
Mem0SearchInput,
|
|
11
14
|
Mem0SearchTool,
|
|
12
15
|
)
|
|
13
|
-
from aip_agents.tools.memory_search.schema import LongTermMemorySearchInput, MemoryConfig
|
|
16
|
+
from aip_agents.tools.memory_search.schema import LongTermMemoryDeleteInput, LongTermMemorySearchInput, MemoryConfig
|
|
14
17
|
|
|
15
18
|
__all__ = [
|
|
16
19
|
"MemoryConfig",
|
|
20
|
+
"LongTermMemoryDeleteInput",
|
|
17
21
|
"LongTermMemorySearchInput",
|
|
18
22
|
"LongTermMemorySearchTool",
|
|
23
|
+
"Mem0DeleteInput",
|
|
24
|
+
"Mem0DeleteTool",
|
|
19
25
|
"Mem0SearchInput",
|
|
20
26
|
"Mem0SearchTool",
|
|
27
|
+
"MEMORY_DELETE_TOOL_NAME",
|
|
21
28
|
"MEMORY_SEARCH_TOOL_NAME",
|
|
22
29
|
]
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
from aip_agents.tools.memory_search.base import LongTermMemorySearchTool as LongTermMemorySearchTool
|
|
2
|
-
from aip_agents.tools.memory_search.mem0 import MEMORY_SEARCH_TOOL_NAME as MEMORY_SEARCH_TOOL_NAME, Mem0SearchInput as Mem0SearchInput, Mem0SearchTool as Mem0SearchTool
|
|
3
|
-
from aip_agents.tools.memory_search.schema import LongTermMemorySearchInput as LongTermMemorySearchInput, MemoryConfig as MemoryConfig
|
|
2
|
+
from aip_agents.tools.memory_search.mem0 import MEMORY_DELETE_TOOL_NAME as MEMORY_DELETE_TOOL_NAME, MEMORY_SEARCH_TOOL_NAME as MEMORY_SEARCH_TOOL_NAME, Mem0DeleteInput as Mem0DeleteInput, Mem0DeleteTool as Mem0DeleteTool, Mem0SearchInput as Mem0SearchInput, Mem0SearchTool as Mem0SearchTool
|
|
3
|
+
from aip_agents.tools.memory_search.schema import LongTermMemoryDeleteInput as LongTermMemoryDeleteInput, LongTermMemorySearchInput as LongTermMemorySearchInput, MemoryConfig as MemoryConfig
|
|
4
4
|
|
|
5
|
-
__all__ = ['MemoryConfig', 'LongTermMemorySearchInput', 'LongTermMemorySearchTool', 'Mem0SearchInput', 'Mem0SearchTool', 'MEMORY_SEARCH_TOOL_NAME']
|
|
5
|
+
__all__ = ['MemoryConfig', 'LongTermMemoryDeleteInput', 'LongTermMemorySearchInput', 'LongTermMemorySearchTool', 'Mem0DeleteInput', 'Mem0DeleteTool', 'Mem0SearchInput', 'Mem0SearchTool', 'MEMORY_DELETE_TOOL_NAME', 'MEMORY_SEARCH_TOOL_NAME']
|
|
@@ -13,13 +13,14 @@ from langchain_core.runnables import RunnableConfig
|
|
|
13
13
|
|
|
14
14
|
from aip_agents.memory.constants import MemoryDefaults
|
|
15
15
|
from aip_agents.tools.memory_search.base import LongTermMemorySearchTool
|
|
16
|
-
from aip_agents.tools.memory_search.schema import LongTermMemorySearchInput
|
|
16
|
+
from aip_agents.tools.memory_search.schema import LongTermMemoryDeleteInput, LongTermMemorySearchInput
|
|
17
17
|
from aip_agents.utils.datetime import is_valid_date_string, next_day_iso
|
|
18
18
|
from aip_agents.utils.logger import get_logger
|
|
19
19
|
|
|
20
20
|
logger = get_logger(__name__)
|
|
21
21
|
|
|
22
22
|
MEMORY_SEARCH_TOOL_NAME = "built_in_mem0_search"
|
|
23
|
+
MEMORY_DELETE_TOOL_NAME = "built_in_mem0_delete"
|
|
23
24
|
|
|
24
25
|
|
|
25
26
|
class Mem0SearchTool(LongTermMemorySearchTool):
|
|
@@ -256,3 +257,115 @@ class Mem0SearchTool(LongTermMemorySearchTool):
|
|
|
256
257
|
|
|
257
258
|
|
|
258
259
|
Mem0SearchInput = LongTermMemorySearchInput
|
|
260
|
+
|
|
261
|
+
|
|
262
|
+
class Mem0DeleteTool(LongTermMemorySearchTool):
|
|
263
|
+
"""Mem0-specific implementation of the long-term memory delete tool."""
|
|
264
|
+
|
|
265
|
+
name: str = MEMORY_DELETE_TOOL_NAME
|
|
266
|
+
description: str = (
|
|
267
|
+
"Delete memories from long-term mem0 storage. Supports three modes:\n"
|
|
268
|
+
"1. DELETE BY IDS: Provide 'memory_ids'\n"
|
|
269
|
+
"2. DELETE BY QUERY: Provide 'query'\n"
|
|
270
|
+
"3. DELETE ALL: Provide 'delete_all=true' with no query/IDs\n"
|
|
271
|
+
)
|
|
272
|
+
args_schema: type[LongTermMemoryDeleteInput] = LongTermMemoryDeleteInput
|
|
273
|
+
LOG_PREFIX: ClassVar[str] = "Mem0DeleteTool"
|
|
274
|
+
METADATA_FILTER_BLOCKLIST: ClassVar[set[str]] = {"user_id", "memory_user_id"}
|
|
275
|
+
|
|
276
|
+
async def _arun(
|
|
277
|
+
self,
|
|
278
|
+
query: str | None = None,
|
|
279
|
+
config: RunnableConfig | None = None,
|
|
280
|
+
run_manager: Any | None = None,
|
|
281
|
+
**kwargs: Any,
|
|
282
|
+
) -> str:
|
|
283
|
+
"""Execute the memory delete asynchronously for LangChain.
|
|
284
|
+
|
|
285
|
+
Args:
|
|
286
|
+
query: Semantic delete query when provided.
|
|
287
|
+
config: Runnable configuration containing LangChain metadata.
|
|
288
|
+
run_manager: LangChain callbacks (unused).
|
|
289
|
+
**kwargs: Additional arguments such as ``memory_ids``, ``delete_all``, ``metadata``.
|
|
290
|
+
|
|
291
|
+
Returns:
|
|
292
|
+
str: JSON-encoded delete result or an error message.
|
|
293
|
+
"""
|
|
294
|
+
logger.info("%s: Received config: %s", self.LOG_PREFIX, config)
|
|
295
|
+
|
|
296
|
+
memory_ids: list[str] | None = kwargs.get("memory_ids")
|
|
297
|
+
delete_all: bool | None = kwargs.get("delete_all")
|
|
298
|
+
threshold: float | None = kwargs.get("threshold")
|
|
299
|
+
top_k: int | None = kwargs.get("top_k")
|
|
300
|
+
categories: list[str] | None = kwargs.get("categories")
|
|
301
|
+
metadata: dict[str, Any] | None = kwargs.get("metadata")
|
|
302
|
+
|
|
303
|
+
user_id = self._resolve_user_id(metadata=metadata, config=config)
|
|
304
|
+
|
|
305
|
+
metadata_filter = None
|
|
306
|
+
if isinstance(metadata, dict):
|
|
307
|
+
metadata_filter = {k: v for k, v in metadata.items() if k not in self.METADATA_FILTER_BLOCKLIST} or None
|
|
308
|
+
|
|
309
|
+
if memory_ids:
|
|
310
|
+
if not hasattr(self.memory, "delete"):
|
|
311
|
+
return f"Error executing memory tool '{self.name}': backend does not support delete()"
|
|
312
|
+
mode = "ids"
|
|
313
|
+
result = self.memory.delete( # type: ignore[attr-defined]
|
|
314
|
+
memory_ids=memory_ids,
|
|
315
|
+
user_id=user_id,
|
|
316
|
+
metadata=metadata_filter,
|
|
317
|
+
categories=categories,
|
|
318
|
+
)
|
|
319
|
+
elif query:
|
|
320
|
+
if not hasattr(self.memory, "delete_by_query"):
|
|
321
|
+
return f"Error executing memory tool '{self.name}': backend does not support delete_by_query()"
|
|
322
|
+
mode = "query"
|
|
323
|
+
filters: dict[str, Any] | None = None
|
|
324
|
+
if metadata_filter or categories:
|
|
325
|
+
filters = {}
|
|
326
|
+
if metadata_filter:
|
|
327
|
+
filters["metadata"] = metadata_filter
|
|
328
|
+
if categories:
|
|
329
|
+
filters["categories"] = categories
|
|
330
|
+
result = self.memory.delete_by_query( # type: ignore[attr-defined]
|
|
331
|
+
query=query,
|
|
332
|
+
user_id=user_id,
|
|
333
|
+
threshold=threshold,
|
|
334
|
+
top_k=top_k,
|
|
335
|
+
filters=filters,
|
|
336
|
+
)
|
|
337
|
+
elif delete_all:
|
|
338
|
+
if not hasattr(self.memory, "delete"):
|
|
339
|
+
return f"Error executing memory tool '{self.name}': backend does not support delete()"
|
|
340
|
+
mode = "all"
|
|
341
|
+
result = self.memory.delete( # type: ignore[attr-defined]
|
|
342
|
+
memory_ids=None,
|
|
343
|
+
user_id=user_id,
|
|
344
|
+
metadata=metadata_filter,
|
|
345
|
+
categories=categories,
|
|
346
|
+
)
|
|
347
|
+
else:
|
|
348
|
+
return f"Error executing memory tool '{self.name}': provide memory_ids, query, or delete_all=true."
|
|
349
|
+
|
|
350
|
+
count = None
|
|
351
|
+
if isinstance(result, dict):
|
|
352
|
+
count = result.get("count") or result.get("deleted") or result.get("total")
|
|
353
|
+
|
|
354
|
+
logger.info(
|
|
355
|
+
"%s: delete mode=%s user_id='%s' count=%s",
|
|
356
|
+
self.LOG_PREFIX,
|
|
357
|
+
mode,
|
|
358
|
+
user_id,
|
|
359
|
+
count if count is not None else "unknown",
|
|
360
|
+
)
|
|
361
|
+
|
|
362
|
+
payload = {"status": "success", "mode": mode}
|
|
363
|
+
try:
|
|
364
|
+
json.dumps(result)
|
|
365
|
+
payload["result"] = result
|
|
366
|
+
except TypeError:
|
|
367
|
+
payload["result"] = str(result)
|
|
368
|
+
return json.dumps(payload)
|
|
369
|
+
|
|
370
|
+
|
|
371
|
+
Mem0DeleteInput = LongTermMemoryDeleteInput
|
|
@@ -1,13 +1,14 @@
|
|
|
1
1
|
from _typeshed import Incomplete
|
|
2
2
|
from aip_agents.memory.constants import MemoryDefaults as MemoryDefaults
|
|
3
3
|
from aip_agents.tools.memory_search.base import LongTermMemorySearchTool as LongTermMemorySearchTool
|
|
4
|
-
from aip_agents.tools.memory_search.schema import LongTermMemorySearchInput as LongTermMemorySearchInput
|
|
4
|
+
from aip_agents.tools.memory_search.schema import LongTermMemoryDeleteInput as LongTermMemoryDeleteInput, LongTermMemorySearchInput as LongTermMemorySearchInput
|
|
5
5
|
from aip_agents.utils.datetime import is_valid_date_string as is_valid_date_string, next_day_iso as next_day_iso
|
|
6
6
|
from aip_agents.utils.logger import get_logger as get_logger
|
|
7
7
|
from typing import ClassVar
|
|
8
8
|
|
|
9
9
|
logger: Incomplete
|
|
10
10
|
MEMORY_SEARCH_TOOL_NAME: str
|
|
11
|
+
MEMORY_DELETE_TOOL_NAME: str
|
|
11
12
|
|
|
12
13
|
class Mem0SearchTool(LongTermMemorySearchTool):
|
|
13
14
|
"""Mem0-specific implementation of the long-term memory search tool."""
|
|
@@ -17,3 +18,12 @@ class Mem0SearchTool(LongTermMemorySearchTool):
|
|
|
17
18
|
LOG_PREFIX: ClassVar[str]
|
|
18
19
|
METADATA_FILTER_BLOCKLIST: ClassVar[set[str]]
|
|
19
20
|
Mem0SearchInput = LongTermMemorySearchInput
|
|
21
|
+
|
|
22
|
+
class Mem0DeleteTool(LongTermMemorySearchTool):
|
|
23
|
+
"""Mem0-specific implementation of the long-term memory delete tool."""
|
|
24
|
+
name: str
|
|
25
|
+
description: str
|
|
26
|
+
args_schema: type[LongTermMemoryDeleteInput]
|
|
27
|
+
LOG_PREFIX: ClassVar[str]
|
|
28
|
+
METADATA_FILTER_BLOCKLIST: ClassVar[set[str]]
|
|
29
|
+
Mem0DeleteInput = LongTermMemoryDeleteInput
|
|
@@ -46,3 +46,36 @@ class LongTermMemorySearchInput(BaseModel):
|
|
|
46
46
|
None,
|
|
47
47
|
description="Optional metadata dict to filter by (exact key-value match).",
|
|
48
48
|
)
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
class LongTermMemoryDeleteInput(BaseModel):
|
|
52
|
+
"""Input schema for unified long-term memory deletion."""
|
|
53
|
+
|
|
54
|
+
query: str | None = Field(
|
|
55
|
+
None,
|
|
56
|
+
description="Semantic query describing memories to delete. If provided, delete_by_user_query is used.",
|
|
57
|
+
)
|
|
58
|
+
memory_ids: list[str] | None = Field(
|
|
59
|
+
None,
|
|
60
|
+
description="Optional list of memory IDs to delete directly.",
|
|
61
|
+
)
|
|
62
|
+
delete_all: bool | None = Field(
|
|
63
|
+
None,
|
|
64
|
+
description="When True and no query/IDs are provided, delete all memories for the user scope.",
|
|
65
|
+
)
|
|
66
|
+
top_k: int | None = Field(
|
|
67
|
+
None,
|
|
68
|
+
description="Optional maximum number of memories to delete by query.",
|
|
69
|
+
)
|
|
70
|
+
threshold: float | None = Field(
|
|
71
|
+
None,
|
|
72
|
+
description="Optional semantic threshold for delete_by_user_query.",
|
|
73
|
+
)
|
|
74
|
+
categories: list[str] | None = Field(
|
|
75
|
+
None,
|
|
76
|
+
description="Optional categories to filter by (uses 'in' operator).",
|
|
77
|
+
)
|
|
78
|
+
metadata: dict[str, Any] | None = Field(
|
|
79
|
+
None,
|
|
80
|
+
description="Optional metadata dict to filter by (exact key-value match).",
|
|
81
|
+
)
|
|
@@ -13,3 +13,13 @@ class LongTermMemorySearchInput(BaseModel):
|
|
|
13
13
|
limit: int | None
|
|
14
14
|
categories: list[str] | None
|
|
15
15
|
metadata: dict[str, Any] | None
|
|
16
|
+
|
|
17
|
+
class LongTermMemoryDeleteInput(BaseModel):
|
|
18
|
+
"""Input schema for unified long-term memory deletion."""
|
|
19
|
+
query: str | None
|
|
20
|
+
memory_ids: list[str] | None
|
|
21
|
+
delete_all: bool | None
|
|
22
|
+
top_k: int | None
|
|
23
|
+
threshold: float | None
|
|
24
|
+
categories: list[str] | None
|
|
25
|
+
metadata: dict[str, Any] | None
|
|
@@ -8,9 +8,13 @@ Authors:
|
|
|
8
8
|
"""
|
|
9
9
|
|
|
10
10
|
from aip_agents.tools.memory_search import (
|
|
11
|
+
MEMORY_DELETE_TOOL_NAME,
|
|
11
12
|
MEMORY_SEARCH_TOOL_NAME,
|
|
13
|
+
LongTermMemoryDeleteInput,
|
|
12
14
|
LongTermMemorySearchInput,
|
|
13
15
|
LongTermMemorySearchTool,
|
|
16
|
+
Mem0DeleteInput,
|
|
17
|
+
Mem0DeleteTool,
|
|
14
18
|
Mem0SearchInput,
|
|
15
19
|
Mem0SearchTool,
|
|
16
20
|
MemoryConfig,
|
|
@@ -18,9 +22,13 @@ from aip_agents.tools.memory_search import (
|
|
|
18
22
|
|
|
19
23
|
__all__ = [
|
|
20
24
|
"MemoryConfig",
|
|
25
|
+
"LongTermMemoryDeleteInput",
|
|
21
26
|
"LongTermMemorySearchInput",
|
|
22
27
|
"LongTermMemorySearchTool",
|
|
28
|
+
"Mem0DeleteInput",
|
|
29
|
+
"Mem0DeleteTool",
|
|
23
30
|
"Mem0SearchInput",
|
|
24
31
|
"Mem0SearchTool",
|
|
32
|
+
"MEMORY_DELETE_TOOL_NAME",
|
|
25
33
|
"MEMORY_SEARCH_TOOL_NAME",
|
|
26
34
|
]
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
from aip_agents.tools.memory_search import LongTermMemorySearchInput as LongTermMemorySearchInput, LongTermMemorySearchTool as LongTermMemorySearchTool, MEMORY_SEARCH_TOOL_NAME as MEMORY_SEARCH_TOOL_NAME, Mem0SearchInput as Mem0SearchInput, Mem0SearchTool as Mem0SearchTool, MemoryConfig as MemoryConfig
|
|
1
|
+
from aip_agents.tools.memory_search import LongTermMemoryDeleteInput as LongTermMemoryDeleteInput, LongTermMemorySearchInput as LongTermMemorySearchInput, LongTermMemorySearchTool as LongTermMemorySearchTool, MEMORY_DELETE_TOOL_NAME as MEMORY_DELETE_TOOL_NAME, MEMORY_SEARCH_TOOL_NAME as MEMORY_SEARCH_TOOL_NAME, Mem0DeleteInput as Mem0DeleteInput, Mem0DeleteTool as Mem0DeleteTool, Mem0SearchInput as Mem0SearchInput, Mem0SearchTool as Mem0SearchTool, MemoryConfig as MemoryConfig
|
|
2
2
|
|
|
3
|
-
__all__ = ['MemoryConfig', 'LongTermMemorySearchInput', 'LongTermMemorySearchTool', 'Mem0SearchInput', 'Mem0SearchTool', 'MEMORY_SEARCH_TOOL_NAME']
|
|
3
|
+
__all__ = ['MemoryConfig', 'LongTermMemoryDeleteInput', 'LongTermMemorySearchInput', 'LongTermMemorySearchTool', 'Mem0DeleteInput', 'Mem0DeleteTool', 'Mem0SearchInput', 'Mem0SearchTool', 'MEMORY_DELETE_TOOL_NAME', 'MEMORY_SEARCH_TOOL_NAME']
|
|
@@ -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
|
|