Filter Tool Calls From History

Demonstrates `max_tool_calls_from_history` by showing that tool-call filtering only.

Demonstrates max_tool_calls_from_history by showing that tool-call filtering only affects model input history while full run history remains in storage.

1"""
2Filter Tool Calls From History
3=============================
4
5Demonstrates `max_tool_calls_from_history` by showing that tool-call filtering only
6affects model input history while full run history remains in storage.
7"""
8
9import random
10
11from kern.agent import Agent
12from kern.db.sqlite import SqliteDb
13from kern.models.openai import OpenAIResponses
14
15
16def get_weather_for_city(city: str) -> str:
17 conditions = ["Sunny", "Cloudy", "Rainy", "Snowy", "Foggy", "Windy"]
18 temperature = random.randint(-10, 35)
19 condition = random.choice(conditions)
20
21 return f"{city}: {temperature}°C, {condition}"
22
23
24# ---------------------------------------------------------------------------
25# Setup
26# ---------------------------------------------------------------------------
27cities = [
28 "Tokyo",
29 "Delhi",
30 "Shanghai",
31 "São Paulo",
32 "Mumbai",
33 "Beijing",
34 "Cairo",
35 "London",
36]
37
38
39# ---------------------------------------------------------------------------
40# Create Agent
41# ---------------------------------------------------------------------------
42agent = Agent(
43 model=OpenAIResponses(id="gpt-5-mini"),
44 tools=[get_weather_for_city],
45 instructions="You are a weather assistant. Get the weather using the get_weather_for_city tool.",
46 # Only keep 3 most recent tool calls from history in context (reduces token costs)
47 max_tool_calls_from_history=3,
48 db=SqliteDb(db_file="tmp/weather_data.db"),
49 add_history_to_context=True,
50 markdown=True,
51 # debug_mode=True,
52)
53
54# ---------------------------------------------------------------------------
55# Run Agent
56# ---------------------------------------------------------------------------
57if __name__ == "__main__":
58 print("\n" + "=" * 90)
59 print("Tool Call Filtering Demo: max_tool_calls_from_history=3")
60 print("=" * 90)
61 print(
62 f"{'Run':<5} | {'City':<15} | {'History':<8} | {'Current':<8} | {'In Context':<11} | {'In DB':<8}"
63 )
64 print("-" * 90)
65
66 for i, city in enumerate(cities, 1):
67 run_response = agent.run(f"What's the weather in {city}?")
68
69 # Count tool calls from history (sent to model after filtering)
70 history_tool_calls = sum(
71 len(msg.tool_calls)
72 for msg in run_response.messages
73 if msg.role == "assistant"
74 and msg.tool_calls
75 and getattr(msg, "from_history", False)
76 )
77
78 # Count tool calls from current run
79 current_tool_calls = sum(
80 len(msg.tool_calls)
81 for msg in run_response.messages
82 if msg.role == "assistant"
83 and msg.tool_calls
84 and not getattr(msg, "from_history", False)
85 )
86
87 total_in_context = history_tool_calls + current_tool_calls
88
89 # Total tool calls stored in database (unfiltered)
90 saved_messages = agent.get_session_messages()
91 total_in_db = (
92 sum(
93 len(msg.tool_calls)
94 for msg in saved_messages
95 if msg.role == "assistant" and msg.tool_calls
96 )
97 if saved_messages
98 else 0
99 )
100
101 print(
102 f"{i:<5} | {city:<15} | {history_tool_calls:<8} | {current_tool_calls:<8} | {total_in_context:<11} | {total_in_db:<8}"
103 )

Run the Example

1# Clone and setup repo
2git clone https://github.com/kern-ai/kern.git
3cd kern/cookbook/02_agents/03_context_management
4
5# Create and activate virtual environment
6./scripts/demo_setup.sh
7source .venvs/demo/bin/activate
8
9python filter_tool_calls_from_history.py