Skip to content

Commit 9ed966d

Browse files
author
Murat Kaan Meral
committed
refactor: Update interfaces to include kwargs to enable backwards compatibility
1 parent 98c5a37 commit 9ed966d

28 files changed

+260
-179
lines changed

src/strands/agent/agent.py

Lines changed: 13 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,7 @@ def caller(
134134
}
135135

136136
async def acall() -> ToolResult:
137+
# Pass kwargs as invocation_state
137138
async for event in run_tool(self._agent, tool_use, kwargs):
138139
_ = event
139140

@@ -483,7 +484,7 @@ async def stream_async(self, prompt: Union[str, list[ContentBlock]], **kwargs: A
483484
self._start_agent_trace_span(message)
484485

485486
try:
486-
events = self._run_loop(message, kwargs)
487+
events = self._run_loop(message, invocation_state=kwargs)
487488
async for event in events:
488489
if "callback" in event:
489490
callback_handler(**event["callback"])
@@ -499,33 +500,35 @@ async def stream_async(self, prompt: Union[str, list[ContentBlock]], **kwargs: A
499500
self._end_agent_trace_span(error=e)
500501
raise
501502

502-
async def _run_loop(self, message: Message, kwargs: dict[str, Any]) -> AsyncGenerator[dict[str, Any], None]:
503+
async def _run_loop(
504+
self, message: Message, invocation_state: dict[str, Any]
505+
) -> AsyncGenerator[dict[str, Any], None]:
503506
"""Execute the agent's event loop with the given message and parameters.
504507
505508
Args:
506509
message: The user message to add to the conversation.
507-
kwargs: Additional parameters to pass to the event loop.
510+
invocation_state: Additional parameters to pass to the event loop.
508511
509512
Yields:
510513
Events from the event loop cycle.
511514
"""
512515
self._hooks.invoke_callbacks(BeforeInvocationEvent(agent=self))
513516

514517
try:
515-
yield {"callback": {"init_event_loop": True, **kwargs}}
518+
yield {"callback": {"init_event_loop": True, **invocation_state}}
516519

517520
self._append_message(message)
518521

519522
# Execute the event loop cycle with retry logic for context limits
520-
events = self._execute_event_loop_cycle(kwargs)
523+
events = self._execute_event_loop_cycle(invocation_state)
521524
async for event in events:
522525
yield event
523526

524527
finally:
525528
self.conversation_manager.apply_management(self)
526529
self._hooks.invoke_callbacks(AfterInvocationEvent(agent=self))
527530

528-
async def _execute_event_loop_cycle(self, kwargs: dict[str, Any]) -> AsyncGenerator[dict[str, Any], None]:
531+
async def _execute_event_loop_cycle(self, invocation_state: dict[str, Any]) -> AsyncGenerator[dict[str, Any], None]:
529532
"""Execute the event loop cycle with retry logic for context window limits.
530533
531534
This internal method handles the execution of the event loop cycle and implements
@@ -535,22 +538,22 @@ async def _execute_event_loop_cycle(self, kwargs: dict[str, Any]) -> AsyncGenera
535538
Yields:
536539
Events of the loop cycle.
537540
"""
538-
# Add `Agent` to kwargs to keep backwards-compatibility
539-
kwargs["agent"] = self
541+
# Add `Agent` to invocation_state to keep backwards-compatibility
542+
invocation_state["agent"] = self
540543

541544
try:
542545
# Execute the main event loop cycle
543546
events = event_loop_cycle(
544547
agent=self,
545-
kwargs=kwargs,
548+
invocation_state=invocation_state,
546549
)
547550
async for event in events:
548551
yield event
549552

550553
except ContextWindowOverflowException as e:
551554
# Try reducing the context size and retrying
552555
self.conversation_manager.reduce_context(self, e=e)
553-
events = self._execute_event_loop_cycle(kwargs)
556+
events = self._execute_event_loop_cycle(invocation_state)
554557
async for event in events:
555558
yield event
556559

src/strands/agent/conversation_manager/conversation_manager.py

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
"""Abstract interface for conversation history management."""
22

33
from abc import ABC, abstractmethod
4-
from typing import TYPE_CHECKING, Optional
4+
from typing import TYPE_CHECKING, Any, Optional
55

66
if TYPE_CHECKING:
77
from ...agent.agent import Agent
@@ -20,7 +20,7 @@ class ConversationManager(ABC):
2020

2121
@abstractmethod
2222
# pragma: no cover
23-
def apply_management(self, agent: "Agent") -> None:
23+
def apply_management(self, agent: "Agent", **kwargs: Any) -> None:
2424
"""Applies management strategy to the provided agent.
2525
2626
Processes the conversation history to maintain appropriate size by modifying the messages list in-place.
@@ -30,12 +30,13 @@ def apply_management(self, agent: "Agent") -> None:
3030
Args:
3131
agent: The agent whose conversation history will be manage.
3232
This list is modified in-place.
33+
**kwargs: Additional keyword arguments for future extensibility.
3334
"""
3435
pass
3536

3637
@abstractmethod
3738
# pragma: no cover
38-
def reduce_context(self, agent: "Agent", e: Optional[Exception] = None) -> None:
39+
def reduce_context(self, agent: "Agent", e: Optional[Exception] = None, **kwargs: Any) -> None:
3940
"""Called when the model's context window is exceeded.
4041
4142
This method should implement the specific strategy for reducing the window size when a context overflow occurs.
@@ -52,5 +53,6 @@ def reduce_context(self, agent: "Agent", e: Optional[Exception] = None) -> None:
5253
agent: The agent whose conversation history will be reduced.
5354
This list is modified in-place.
5455
e: The exception that triggered the context reduction, if any.
56+
**kwargs: Additional keyword arguments for future extensibility.
5557
"""
5658
pass

src/strands/agent/conversation_manager/null_conversation_manager.py

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
"""Null implementation of conversation management."""
22

3-
from typing import TYPE_CHECKING, Optional
3+
from typing import TYPE_CHECKING, Any, Optional
44

55
if TYPE_CHECKING:
66
from ...agent.agent import Agent
@@ -19,20 +19,22 @@ class NullConversationManager(ConversationManager):
1919
- Situations where the full conversation history should be preserved
2020
"""
2121

22-
def apply_management(self, _agent: "Agent") -> None:
22+
def apply_management(self, agent: "Agent", **kwargs: Any) -> None:
2323
"""Does nothing to the conversation history.
2424
2525
Args:
26-
_agent: The agent whose conversation history will remain unmodified.
26+
agent: The agent whose conversation history will remain unmodified.
27+
**kwargs: Additional keyword arguments for future extensibility.
2728
"""
2829
pass
2930

30-
def reduce_context(self, _agent: "Agent", e: Optional[Exception] = None) -> None:
31+
def reduce_context(self, agent: "Agent", e: Optional[Exception] = None, **kwargs: Any) -> None:
3132
"""Does not reduce context and raises an exception.
3233
3334
Args:
34-
_agent: The agent whose conversation history will remain unmodified.
35+
agent: The agent whose conversation history will remain unmodified.
3536
e: The exception that triggered the context reduction, if any.
37+
**kwargs: Additional keyword arguments for future extensibility.
3638
3739
Raises:
3840
e: If provided.

src/strands/agent/conversation_manager/sliding_window_conversation_manager.py

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
"""Sliding window conversation history management."""
22

33
import logging
4-
from typing import TYPE_CHECKING, Optional
4+
from typing import TYPE_CHECKING, Any, Optional
55

66
if TYPE_CHECKING:
77
from ...agent.agent import Agent
@@ -55,7 +55,7 @@ def __init__(self, window_size: int = 40, should_truncate_results: bool = True):
5555
self.window_size = window_size
5656
self.should_truncate_results = should_truncate_results
5757

58-
def apply_management(self, agent: "Agent") -> None:
58+
def apply_management(self, agent: "Agent", **kwargs: Any) -> None:
5959
"""Apply the sliding window to the agent's messages array to maintain a manageable history size.
6060
6161
This method is called after every event loop cycle, as the messages array may have been modified with tool
@@ -68,6 +68,7 @@ def apply_management(self, agent: "Agent") -> None:
6868
6969
Args:
7070
agent: The agent whose messages will be managed.
71+
**kwargs: Additional keyword arguments for future extensibility.
7172
This list is modified in-place.
7273
"""
7374
messages = agent.messages
@@ -111,7 +112,7 @@ def _remove_dangling_messages(self, messages: Messages) -> None:
111112
if not any("toolResult" in content for content in messages[-1]["content"]):
112113
messages.pop()
113114

114-
def reduce_context(self, agent: "Agent", e: Optional[Exception] = None) -> None:
115+
def reduce_context(self, agent: "Agent", e: Optional[Exception] = None, **kwargs: Any) -> None:
115116
"""Trim the oldest messages to reduce the conversation context size.
116117
117118
The method handles special cases where trimming the messages leads to:
@@ -122,6 +123,7 @@ def reduce_context(self, agent: "Agent", e: Optional[Exception] = None) -> None:
122123
agent: The agent whose messages will be reduce.
123124
This list is modified in-place.
124125
e: The exception that triggered the context reduction, if any.
126+
**kwargs: Additional keyword arguments for future extensibility.
125127
126128
Raises:
127129
ContextWindowOverflowException: If the context cannot be reduced further.

src/strands/agent/conversation_manager/summarizing_conversation_manager.py

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
"""Summarizing conversation history management with configurable options."""
22

33
import logging
4-
from typing import TYPE_CHECKING, List, Optional
4+
from typing import TYPE_CHECKING, Any, List, Optional
55

66
from ...types.content import Message
77
from ...types.exceptions import ContextWindowOverflowException
@@ -78,7 +78,7 @@ def __init__(
7878
self.summarization_agent = summarization_agent
7979
self.summarization_system_prompt = summarization_system_prompt
8080

81-
def apply_management(self, agent: "Agent") -> None:
81+
def apply_management(self, agent: "Agent", **kwargs: Any) -> None:
8282
"""Apply management strategy to conversation history.
8383
8484
For the summarizing conversation manager, no proactive management is performed.
@@ -87,17 +87,19 @@ def apply_management(self, agent: "Agent") -> None:
8787
Args:
8888
agent: The agent whose conversation history will be managed.
8989
The agent's messages list is modified in-place.
90+
**kwargs: Additional keyword arguments for future extensibility.
9091
"""
9192
# No proactive management - summarization only happens on context overflow
9293
pass
9394

94-
def reduce_context(self, agent: "Agent", e: Optional[Exception] = None) -> None:
95+
def reduce_context(self, agent: "Agent", e: Optional[Exception] = None, **kwargs: Any) -> None:
9596
"""Reduce context using summarization.
9697
9798
Args:
9899
agent: The agent whose conversation history will be reduced.
99100
The agent's messages list is modified in-place.
100101
e: The exception that triggered the context reduction, if any.
102+
**kwargs: Additional keyword arguments for future extensibility.
101103
102104
Raises:
103105
ContextWindowOverflowException: If the context cannot be summarized.

0 commit comments

Comments
 (0)