ragbits-agents 1.4.0.dev202601310254__tar.gz → 1.4.0.dev202602030301__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (51) hide show
  1. {ragbits_agents-1.4.0.dev202601310254 → ragbits_agents-1.4.0.dev202602030301}/CHANGELOG.md +1 -2
  2. {ragbits_agents-1.4.0.dev202601310254 → ragbits_agents-1.4.0.dev202602030301}/PKG-INFO +2 -2
  3. {ragbits_agents-1.4.0.dev202601310254 → ragbits_agents-1.4.0.dev202602030301}/pyproject.toml +2 -2
  4. {ragbits_agents-1.4.0.dev202601310254 → ragbits_agents-1.4.0.dev202602030301}/src/ragbits/agents/_main.py +4 -5
  5. {ragbits_agents-1.4.0.dev202601310254 → ragbits_agents-1.4.0.dev202602030301}/src/ragbits/agents/hooks/manager.py +8 -7
  6. {ragbits_agents-1.4.0.dev202601310254 → ragbits_agents-1.4.0.dev202602030301}/src/ragbits/agents/hooks/types.py +7 -6
  7. {ragbits_agents-1.4.0.dev202601310254 → ragbits_agents-1.4.0.dev202602030301}/tests/unit/conftest.py +4 -2
  8. {ragbits_agents-1.4.0.dev202601310254 → ragbits_agents-1.4.0.dev202602030301}/tests/unit/hooks/test_manager.py +4 -2
  9. {ragbits_agents-1.4.0.dev202601310254 → ragbits_agents-1.4.0.dev202602030301}/tests/unit/hooks/test_types.py +14 -6
  10. {ragbits_agents-1.4.0.dev202601310254 → ragbits_agents-1.4.0.dev202602030301}/.gitignore +0 -0
  11. {ragbits_agents-1.4.0.dev202601310254 → ragbits_agents-1.4.0.dev202602030301}/README.md +0 -0
  12. {ragbits_agents-1.4.0.dev202601310254 → ragbits_agents-1.4.0.dev202602030301}/src/ragbits/agents/__init__.py +0 -0
  13. {ragbits_agents-1.4.0.dev202601310254 → ragbits_agents-1.4.0.dev202602030301}/src/ragbits/agents/a2a/__init__.py +0 -0
  14. {ragbits_agents-1.4.0.dev202601310254 → ragbits_agents-1.4.0.dev202602030301}/src/ragbits/agents/a2a/server.py +0 -0
  15. {ragbits_agents-1.4.0.dev202601310254 → ragbits_agents-1.4.0.dev202602030301}/src/ragbits/agents/cli.py +0 -0
  16. {ragbits_agents-1.4.0.dev202601310254 → ragbits_agents-1.4.0.dev202602030301}/src/ragbits/agents/confirmation.py +0 -0
  17. {ragbits_agents-1.4.0.dev202601310254 → ragbits_agents-1.4.0.dev202602030301}/src/ragbits/agents/exceptions.py +0 -0
  18. {ragbits_agents-1.4.0.dev202601310254 → ragbits_agents-1.4.0.dev202602030301}/src/ragbits/agents/hooks/__init__.py +0 -0
  19. {ragbits_agents-1.4.0.dev202601310254 → ragbits_agents-1.4.0.dev202602030301}/src/ragbits/agents/hooks/base.py +0 -0
  20. {ragbits_agents-1.4.0.dev202601310254 → ragbits_agents-1.4.0.dev202602030301}/src/ragbits/agents/hooks/confirmation.py +0 -0
  21. {ragbits_agents-1.4.0.dev202601310254 → ragbits_agents-1.4.0.dev202602030301}/src/ragbits/agents/mcp/__init__.py +0 -0
  22. {ragbits_agents-1.4.0.dev202601310254 → ragbits_agents-1.4.0.dev202602030301}/src/ragbits/agents/mcp/server.py +0 -0
  23. {ragbits_agents-1.4.0.dev202601310254 → ragbits_agents-1.4.0.dev202602030301}/src/ragbits/agents/mcp/utils.py +0 -0
  24. {ragbits_agents-1.4.0.dev202601310254 → ragbits_agents-1.4.0.dev202602030301}/src/ragbits/agents/post_processors/__init__.py +0 -0
  25. {ragbits_agents-1.4.0.dev202601310254 → ragbits_agents-1.4.0.dev202602030301}/src/ragbits/agents/post_processors/base.py +0 -0
  26. {ragbits_agents-1.4.0.dev202601310254 → ragbits_agents-1.4.0.dev202602030301}/src/ragbits/agents/post_processors/exceptions.py +0 -0
  27. {ragbits_agents-1.4.0.dev202601310254 → ragbits_agents-1.4.0.dev202602030301}/src/ragbits/agents/post_processors/supervisor.py +0 -0
  28. {ragbits_agents-1.4.0.dev202601310254 → ragbits_agents-1.4.0.dev202602030301}/src/ragbits/agents/py.typed +0 -0
  29. {ragbits_agents-1.4.0.dev202601310254 → ragbits_agents-1.4.0.dev202602030301}/src/ragbits/agents/tool.py +0 -0
  30. {ragbits_agents-1.4.0.dev202601310254 → ragbits_agents-1.4.0.dev202602030301}/src/ragbits/agents/tools/__init__.py +0 -0
  31. {ragbits_agents-1.4.0.dev202601310254 → ragbits_agents-1.4.0.dev202602030301}/src/ragbits/agents/tools/memory.py +0 -0
  32. {ragbits_agents-1.4.0.dev202601310254 → ragbits_agents-1.4.0.dev202602030301}/src/ragbits/agents/tools/openai.py +0 -0
  33. {ragbits_agents-1.4.0.dev202601310254 → ragbits_agents-1.4.0.dev202602030301}/src/ragbits/agents/tools/todo.py +0 -0
  34. {ragbits_agents-1.4.0.dev202601310254 → ragbits_agents-1.4.0.dev202602030301}/src/ragbits/agents/tools/types.py +0 -0
  35. {ragbits_agents-1.4.0.dev202601310254 → ragbits_agents-1.4.0.dev202602030301}/src/ragbits/agents/types.py +0 -0
  36. {ragbits_agents-1.4.0.dev202601310254 → ragbits_agents-1.4.0.dev202602030301}/tests/__init__.py +0 -0
  37. {ragbits_agents-1.4.0.dev202601310254 → ragbits_agents-1.4.0.dev202602030301}/tests/unit/__init__.py +0 -0
  38. {ragbits_agents-1.4.0.dev202601310254 → ragbits_agents-1.4.0.dev202602030301}/tests/unit/hooks/__init__.py +0 -0
  39. {ragbits_agents-1.4.0.dev202601310254 → ragbits_agents-1.4.0.dev202602030301}/tests/unit/hooks/conftest.py +0 -0
  40. {ragbits_agents-1.4.0.dev202601310254 → ragbits_agents-1.4.0.dev202602030301}/tests/unit/hooks/test_base.py +0 -0
  41. {ragbits_agents-1.4.0.dev202601310254 → ragbits_agents-1.4.0.dev202602030301}/tests/unit/hooks/test_confirmation.py +0 -0
  42. {ragbits_agents-1.4.0.dev202601310254 → ragbits_agents-1.4.0.dev202602030301}/tests/unit/mcp/helpers.py +0 -0
  43. {ragbits_agents-1.4.0.dev202601310254 → ragbits_agents-1.4.0.dev202602030301}/tests/unit/mcp/test_caching.py +0 -0
  44. {ragbits_agents-1.4.0.dev202601310254 → ragbits_agents-1.4.0.dev202602030301}/tests/unit/mcp/test_connect_disconnect.py +0 -0
  45. {ragbits_agents-1.4.0.dev202601310254 → ragbits_agents-1.4.0.dev202602030301}/tests/unit/mcp/test_exceptions.py +0 -0
  46. {ragbits_agents-1.4.0.dev202601310254 → ragbits_agents-1.4.0.dev202602030301}/tests/unit/mcp/test_mcp_utils.py +0 -0
  47. {ragbits_agents-1.4.0.dev202601310254 → ragbits_agents-1.4.0.dev202602030301}/tests/unit/post_processors/test_base_post_processors.py +0 -0
  48. {ragbits_agents-1.4.0.dev202601310254 → ragbits_agents-1.4.0.dev202602030301}/tests/unit/post_processors/test_supervisor.py +0 -0
  49. {ragbits_agents-1.4.0.dev202601310254 → ragbits_agents-1.4.0.dev202602030301}/tests/unit/test_agent.py +0 -0
  50. {ragbits_agents-1.4.0.dev202601310254 → ragbits_agents-1.4.0.dev202602030301}/tests/unit/tools/test_memory.py +0 -0
  51. {ragbits_agents-1.4.0.dev202601310254 → ragbits_agents-1.4.0.dev202602030301}/tests/unit/tools/test_openai.py +0 -0
@@ -6,7 +6,6 @@
6
6
  - Add Support for Thinking in agents (#837)
7
7
  - Add parallel tool calling support to agents for concurrent tool execution (#836)
8
8
  - TodoOrchestrator & Todo list for agent (#823)
9
- - Support wrapping downstream agents as tools (#818)
10
9
  - Add syntax sugar allowing easier Agents definition (#820)
11
10
  - Add post-processors (#821)
12
11
  - Support streaming from downstream agents (#812)
@@ -17,9 +16,9 @@
17
16
  - Add supervisor post-processor (#830)
18
17
  - Add support for todo lists generated by agents with examples (#827)
19
18
  - Add long-term semantic memory tools for agents (#839)
20
- - Add control over what output from the tool is passed to the LLM (#920)
21
19
  - Add support for confirmation requests in agents (#853) (#914)
22
20
  - Add hooks system (pre- and post-tool) for lifecycle event interception (#914)
21
+ - Add ToolReturn allowing the control which part of the tool output we pass to LLM (#920)
23
22
 
24
23
  ## 1.3.0 (2025-09-11)
25
24
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: ragbits-agents
3
- Version: 1.4.0.dev202601310254
3
+ Version: 1.4.0.dev202602030301
4
4
  Summary: Building blocks for rapid development of GenAI applications
5
5
  Project-URL: Homepage, https://github.com/deepsense-ai/ragbits
6
6
  Project-URL: Bug Reports, https://github.com/deepsense-ai/ragbits/issues
@@ -22,7 +22,7 @@ Classifier: Programming Language :: Python :: 3.13
22
22
  Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
23
23
  Classifier: Topic :: Software Development :: Libraries :: Python Modules
24
24
  Requires-Python: >=3.10
25
- Requires-Dist: ragbits-core==1.4.0.dev202601310254
25
+ Requires-Dist: ragbits-core==1.4.0.dev202602030301
26
26
  Provides-Extra: a2a
27
27
  Requires-Dist: a2a-sdk<1.0.0,>=0.2.9; extra == 'a2a'
28
28
  Requires-Dist: fastapi<1.0.0,>=0.115.0; extra == 'a2a'
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "ragbits-agents"
3
- version = "1.4.0.dev202601310254"
3
+ version = "1.4.0.dev202602030301"
4
4
  description = "Building blocks for rapid development of GenAI applications"
5
5
  readme = "README.md"
6
6
  requires-python = ">=3.10"
@@ -31,7 +31,7 @@ classifiers = [
31
31
  "Topic :: Scientific/Engineering :: Artificial Intelligence",
32
32
  "Topic :: Software Development :: Libraries :: Python Modules",
33
33
  ]
34
- dependencies = ["ragbits-core==1.4.0.dev202601310254"]
34
+ dependencies = ["ragbits-core==1.4.0.dev202602030301"]
35
35
 
36
36
  [project.optional-dependencies]
37
37
  a2a = [
@@ -1036,12 +1036,11 @@ class Agent(
1036
1036
  }
1037
1037
 
1038
1038
  # Execute POST_TOOL hooks with chaining
1039
- post_tool_result = await self.hook_manager.execute_post_tool(
1039
+ post_tool_output = await self.hook_manager.execute_post_tool(
1040
1040
  tool_call=tool_call,
1041
- output=tool_output,
1041
+ tool_return=tool_return,
1042
1042
  error=tool_error,
1043
1043
  )
1044
- tool_output = post_tool_result.output
1045
1044
 
1046
1045
  # Raise error after hooks have been executed
1047
1046
  if tool_error:
@@ -1051,8 +1050,8 @@ class Agent(
1051
1050
  id=tool_call.id,
1052
1051
  name=tool_call.name,
1053
1052
  arguments=tool_call.arguments,
1054
- result=tool_return.value,
1055
- metadata=tool_return.metadata,
1053
+ result=post_tool_output.tool_return.value if post_tool_output.tool_return else None,
1054
+ metadata=post_tool_output.tool_return.metadata if post_tool_output.tool_return else None,
1056
1055
  )
1057
1056
 
1058
1057
  @requires_dependencies(["a2a.types"], "a2a")
@@ -8,11 +8,12 @@ organization, and execution of hooks during lifecycle events.
8
8
  import hashlib
9
9
  import json
10
10
  from collections import defaultdict
11
- from typing import TYPE_CHECKING, Any
11
+ from typing import TYPE_CHECKING
12
12
 
13
13
  from ragbits.agents.confirmation import ConfirmationRequest
14
14
  from ragbits.agents.hooks.base import Hook
15
15
  from ragbits.agents.hooks.types import EventType, PostToolInput, PostToolOutput, PreToolInput, PreToolOutput
16
+ from ragbits.agents.tool import ToolReturn
16
17
  from ragbits.core.llms.base import ToolCall
17
18
 
18
19
  if TYPE_CHECKING:
@@ -156,7 +157,7 @@ class HookManager:
156
157
  async def execute_post_tool(
157
158
  self,
158
159
  tool_call: ToolCall,
159
- output: Any, # noqa: ANN401
160
+ tool_return: ToolReturn | None,
160
161
  error: Exception | None,
161
162
  ) -> PostToolOutput:
162
163
  """
@@ -166,7 +167,7 @@ class HookManager:
166
167
 
167
168
  Args:
168
169
  tool_call: The tool call that was executed
169
- output: The tool output
170
+ tool_return: Object representing the output of the tool (with value passed to the LLM and metadata)
170
171
  error: Any error that occurred
171
172
 
172
173
  Returns:
@@ -175,20 +176,20 @@ class HookManager:
175
176
  hooks = self.get_hooks(EventType.POST_TOOL, tool_call.name)
176
177
 
177
178
  # Start with original output
178
- current_output = output
179
+ current_output = tool_return
179
180
 
180
181
  for hook in hooks:
181
182
  # Create input with current state (chained from previous hook)
182
183
  hook_input = PostToolInput(
183
184
  tool_call=tool_call,
184
- output=current_output,
185
+ tool_return=current_output,
185
186
  error=error,
186
187
  )
187
188
 
188
189
  result: PostToolOutput = await hook.execute(hook_input)
189
190
 
190
191
  # Chain output for next hook
191
- current_output = result.output
192
+ current_output = result.tool_return
192
193
 
193
194
  # Return final chained result
194
- return PostToolOutput(output=current_output)
195
+ return PostToolOutput(tool_return=current_output)
@@ -12,6 +12,7 @@ from typing import Any, Literal, TypeAlias
12
12
  from pydantic import BaseModel, Field, model_validator
13
13
 
14
14
  from ragbits.agents.confirmation import ConfirmationRequest
15
+ from ragbits.agents.tool import ToolReturn
15
16
  from ragbits.core.llms.base import ToolCall
16
17
 
17
18
 
@@ -73,13 +74,13 @@ class PostToolInput(HookEventIO):
73
74
  Attributes:
74
75
  event_type: Always EventType.POST_TOOL (unchangeable)
75
76
  tool_call: The original tool call
76
- output: The result returned by the tool (None if error occurred)
77
+ tool_return: The result returned by the tool (None if error occurred)
77
78
  error: Any error that occurred during execution (None if successful)
78
79
  """
79
80
 
80
81
  event_type: Literal[EventType.POST_TOOL] = Field(default=EventType.POST_TOOL, frozen=True)
81
82
  tool_call: ToolCall
82
- output: Any = None
83
+ tool_return: ToolReturn | None = None
83
84
  error: Exception | None = None
84
85
 
85
86
 
@@ -120,20 +121,20 @@ class PostToolOutput(HookEventIO):
120
121
 
121
122
  Attributes:
122
123
  event_type: Always EventType.POST_TOOL (unchangeable)
123
- output: Tool output to use (original or modified) - always present
124
+ tool_return: Tool output to use (original or modified) - None if the tool execution failed
124
125
 
125
126
  Example:
126
127
  ```python
127
128
  # Pass through unchanged
128
- return PostToolOutput(output=input.output)
129
+ return PostToolOutput(tool_return=input.tool_return)
129
130
 
130
131
  # Modify output
131
- return PostToolOutput(output={"filtered": data})
132
+ return PostToolOutput(tool_return=ToolReturn(value={"filtered": data}))
132
133
  ```
133
134
  """
134
135
 
135
136
  event_type: Literal[EventType.POST_TOOL] = Field(default=EventType.POST_TOOL, frozen=True) # type: ignore[assignment]
136
- output: Any
137
+ tool_return: ToolReturn | None
137
138
 
138
139
 
139
140
  # Type aliases for hook callbacks
@@ -10,6 +10,7 @@ from ragbits.agents.hooks.types import (
10
10
  PreToolInput,
11
11
  PreToolOutput,
12
12
  )
13
+ from ragbits.agents.tool import ToolReturn
13
14
 
14
15
  # Reusable hook callbacks as fixtures
15
16
 
@@ -62,9 +63,10 @@ def append_output():
62
63
 
63
64
  def factory(text: str, prepend: bool = False) -> PostToolHookCallback:
64
65
  async def hook(input_data: PostToolInput) -> PostToolOutput:
66
+ tool_return_value = input_data.tool_return.value if input_data.tool_return is not None else None
65
67
  if prepend:
66
- return PostToolOutput(output=f"{text}{input_data.output}")
67
- return PostToolOutput(output=f"{input_data.output}{text}")
68
+ return PostToolOutput(tool_return=ToolReturn(f"{text}{tool_return_value}"))
69
+ return PostToolOutput(tool_return=ToolReturn(f"{tool_return_value}{text}"))
68
70
 
69
71
  return hook
70
72
 
@@ -18,6 +18,7 @@ from ragbits.agents.hooks.types import (
18
18
  PreToolInput,
19
19
  PreToolOutput,
20
20
  )
21
+ from ragbits.agents.tool import ToolReturn
21
22
  from ragbits.core.llms.base import ToolCall
22
23
 
23
24
 
@@ -154,9 +155,10 @@ class TestPostToolExecution:
154
155
  Hook(event_type=EventType.POST_TOOL, callback=append_output(" + h2"), priority=2),
155
156
  ]
156
157
  )
157
- result = await manager.execute_post_tool(tool_call, output="Original", error=None)
158
+ result = await manager.execute_post_tool(tool_call, tool_return=ToolReturn(value="Original"), error=None)
158
159
 
159
- assert result.output == "Original + h1 + h2"
160
+ assert result.tool_return is not None
161
+ assert result.tool_return.value == "Original + h1 + h2"
160
162
 
161
163
 
162
164
  class TestConfirmationIdGeneration:
@@ -13,6 +13,7 @@ from ragbits.agents.hooks.types import (
13
13
  PreToolInput,
14
14
  PreToolOutput,
15
15
  )
16
+ from ragbits.agents.tool import ToolReturn
16
17
  from ragbits.core.llms.base import ToolCall
17
18
 
18
19
 
@@ -71,18 +72,25 @@ class TestPreToolOutput:
71
72
 
72
73
  class TestPostToolInput:
73
74
  def test_creation_with_output_and_error(self, tool_call: ToolCall):
74
- input_data = PostToolInput(tool_call=tool_call, output="result")
75
+ input_data = PostToolInput(tool_call=tool_call, tool_return=ToolReturn(value="result"))
75
76
  assert input_data.event_type == EventType.POST_TOOL
76
- assert input_data.output == "result"
77
+ assert input_data.tool_return is not None
78
+ assert input_data.tool_return.value == "result"
77
79
  assert input_data.error is None
78
80
 
79
81
  error = ValueError("failed")
80
- input_with_error = PostToolInput(tool_call=tool_call, output=None, error=error)
82
+ input_with_error = PostToolInput(tool_call=tool_call, tool_return=None, error=error)
81
83
  assert input_with_error.error == error
82
84
 
83
85
 
84
86
  class TestPostToolOutput:
85
87
  def test_creation_with_various_outputs(self):
86
- assert PostToolOutput(output="string").output == "string"
87
- assert PostToolOutput(output={"key": "value"}).output == {"key": "value"}
88
- assert PostToolOutput(output=None).output is None
88
+ string_output = PostToolOutput(tool_return=ToolReturn("string"))
89
+ assert string_output.tool_return is not None
90
+ assert string_output.tool_return.value == "string"
91
+
92
+ dict_output = PostToolOutput(tool_return=ToolReturn({"key": "value"}))
93
+ assert dict_output.tool_return is not None
94
+ assert dict_output.tool_return.value == {"key": "value"}
95
+
96
+ assert PostToolOutput(tool_return=None).tool_return is None