Skip to content

Commit bd15b04

Browse files
authored
refactor: Update interfaces to include kwargs to enable backwards compatibility
• **Model Interfaces**: Added `**kwargs` to stream() and structured_output() methods across all model providers (Bedrock, LiteLLM, LlamaAPI, Mistral, Ollama, OpenAI, Writer) • **Tool System**: Refactored tool interfaces to use `invocation_state: dict[str, Any], **kwargs: Any` instead of `kwargs: dict[str, Any]` for better API clarity • **Event Loop**: Updated event loop functions to use `invocation_state` parameter naming for consistency • **Hook System**: Updated tool invocation events (BeforeToolInvocationEvent, AfterToolInvocationEvent) to use `invocation_state` instead of `kwargs` • **Telemetry/Tracing**: Updated tracer methods to use `invocation_state` parameter naming throughout the tracing system • **Documentation**: Added parameter descriptions for all new `**kwargs` parameters
1 parent c306cda commit bd15b04

26 files changed

+256
-177
lines changed

src/strands/agent/agent.py

Lines changed: 13 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -136,6 +136,7 @@ def caller(
136136
}
137137

138138
async def acall() -> ToolResult:
139+
# Pass kwargs as invocation_state
139140
async for event in run_tool(self._agent, tool_use, kwargs):
140141
_ = event
141142

@@ -494,7 +495,7 @@ async def stream_async(self, prompt: Union[str, list[ContentBlock]], **kwargs: A
494495
self._start_agent_trace_span(message)
495496

496497
try:
497-
events = self._run_loop(message, kwargs)
498+
events = self._run_loop(message, invocation_state=kwargs)
498499
async for event in events:
499500
if "callback" in event:
500501
callback_handler(**event["callback"])
@@ -510,33 +511,35 @@ async def stream_async(self, prompt: Union[str, list[ContentBlock]], **kwargs: A
510511
self._end_agent_trace_span(error=e)
511512
raise
512513

513-
async def _run_loop(self, message: Message, kwargs: dict[str, Any]) -> AsyncGenerator[dict[str, Any], None]:
514+
async def _run_loop(
515+
self, message: Message, invocation_state: dict[str, Any]
516+
) -> AsyncGenerator[dict[str, Any], None]:
514517
"""Execute the agent's event loop with the given message and parameters.
515518
516519
Args:
517520
message: The user message to add to the conversation.
518-
kwargs: Additional parameters to pass to the event loop.
521+
invocation_state: Additional parameters to pass to the event loop.
519522
520523
Yields:
521524
Events from the event loop cycle.
522525
"""
523526
self.hooks.invoke_callbacks(BeforeInvocationEvent(agent=self))
524527

525528
try:
526-
yield {"callback": {"init_event_loop": True, **kwargs}}
529+
yield {"callback": {"init_event_loop": True, **invocation_state}}
527530

528531
self._append_message(message)
529532

530533
# Execute the event loop cycle with retry logic for context limits
531-
events = self._execute_event_loop_cycle(kwargs)
534+
events = self._execute_event_loop_cycle(invocation_state)
532535
async for event in events:
533536
yield event
534537

535538
finally:
536539
self.conversation_manager.apply_management(self)
537540
self.hooks.invoke_callbacks(AfterInvocationEvent(agent=self))
538541

539-
async def _execute_event_loop_cycle(self, kwargs: dict[str, Any]) -> AsyncGenerator[dict[str, Any], None]:
542+
async def _execute_event_loop_cycle(self, invocation_state: dict[str, Any]) -> AsyncGenerator[dict[str, Any], None]:
540543
"""Execute the event loop cycle with retry logic for context window limits.
541544
542545
This internal method handles the execution of the event loop cycle and implements
@@ -546,22 +549,22 @@ async def _execute_event_loop_cycle(self, kwargs: dict[str, Any]) -> AsyncGenera
546549
Yields:
547550
Events of the loop cycle.
548551
"""
549-
# Add `Agent` to kwargs to keep backwards-compatibility
550-
kwargs["agent"] = self
552+
# Add `Agent` to invocation_state to keep backwards-compatibility
553+
invocation_state["agent"] = self
551554

552555
try:
553556
# Execute the main event loop cycle
554557
events = event_loop_cycle(
555558
agent=self,
556-
kwargs=kwargs,
559+
invocation_state=invocation_state,
557560
)
558561
async for event in events:
559562
yield event
560563

561564
except ContextWindowOverflowException as e:
562565
# Try reducing the context size and retrying
563566
self.conversation_manager.reduce_context(self, e=e)
564-
events = self._execute_event_loop_cycle(kwargs)
567+
events = self._execute_event_loop_cycle(invocation_state)
565568
async for event in events:
566569
yield event
567570

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
@@ -69,6 +69,7 @@ def apply_management(self, agent: "Agent") -> None:
6969
Args:
7070
agent: The agent whose messages will be managed.
7171
This list is modified in-place.
72+
**kwargs: Additional keyword arguments for future extensibility.
7273
"""
7374
messages = agent.messages
7475
self._remove_dangling_messages(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)