Skip to content

Commit 25c869a

Browse files
Merge branch 'main' into tools/browserbase
2 parents adb21d3 + 6ab2c3c commit 25c869a

File tree

17 files changed

+541
-123
lines changed

17 files changed

+541
-123
lines changed
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
"""
2+
This example shows how to use a remote LanceDB database.
3+
4+
- Set URI obtained from https://cloud.lancedb.com/
5+
- Export `LANCEDB_API_KEY` OR set `api_key` in the `LanceDb` constructor
6+
"""
7+
8+
# install lancedb - `pip install lancedb`
9+
10+
from agno.agent import Agent
11+
from agno.knowledge.pdf_url import PDFUrlKnowledgeBase
12+
from agno.vectordb.lancedb import LanceDb
13+
14+
# Initialize Remote LanceDB
15+
vector_db = LanceDb(
16+
table_name="recipes",
17+
uri="<URI>",
18+
# api_key="<API_KEY>",
19+
)
20+
21+
# Create knowledge base
22+
knowledge_base = PDFUrlKnowledgeBase(
23+
urls=["https://agno-public.s3.amazonaws.com/recipes/ThaiRecipes.pdf"],
24+
vector_db=vector_db,
25+
)
26+
27+
knowledge_base.load(recreate=False) # Comment out after first run
28+
29+
# Create and use the agent
30+
agent = Agent(knowledge=knowledge_base, show_tool_calls=True)
31+
agent.print_response("How to make Tom Kha Gai", markdown=True)
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
from uuid import uuid4
2+
3+
from agno.agent.agent import Agent
4+
from agno.memory.v2.db.sqlite import SqliteMemoryDb
5+
from agno.memory.v2.memory import Memory
6+
from agno.models.openai.chat import OpenAIChat
7+
from agno.storage.sqlite import SqliteStorage
8+
9+
agent_storage = SqliteStorage(
10+
table_name="agent_sessions", db_file="tmp/agent_sessions.db"
11+
)
12+
memory_db = SqliteMemoryDb(table_name="memory", db_file="tmp/memory.db")
13+
memory = Memory(db=memory_db)
14+
15+
# Reset the memory for this example
16+
memory.clear()
17+
18+
19+
session_id = str(uuid4())
20+
user_id = "john_doe@example.com"
21+
22+
agent_1 = Agent(
23+
model=OpenAIChat(id="gpt-4o-mini"),
24+
instructions="You are really friendly and helpful.",
25+
storage=agent_storage,
26+
memory=memory,
27+
add_history_to_messages=True,
28+
enable_user_memories=True,
29+
)
30+
31+
agent_2 = Agent(
32+
model=OpenAIChat(id="gpt-4o-mini"),
33+
instructions="You are really grumpy and mean.",
34+
storage=agent_storage,
35+
memory=memory,
36+
add_history_to_messages=True,
37+
enable_user_memories=True,
38+
)
39+
40+
agent_1.print_response(
41+
"Hi! My name is John Doe.", session_id=session_id, user_id=user_id
42+
)
43+
44+
agent_2.print_response("What is my name?", session_id=session_id, user_id=user_id)
45+
46+
agent_2.print_response(
47+
"I like to hike in the mountains on weekends.",
48+
session_id=session_id,
49+
user_id=user_id,
50+
)
51+
52+
agent_1.print_response("What are my hobbies?", session_id=session_id, user_id=user_id)
53+
54+
agent_1.print_response(
55+
"What have we been discussing? Give me bullet points.",
56+
session_id=session_id,
57+
user_id=user_id,
58+
)

cookbook/agent_concepts/rag/agentic_rag_with_reranking.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,10 @@
2828
),
2929
)
3030

31+
# Comment this out after first run
32+
knowledge_base.load(recreate=False)
33+
34+
3135
agent = Agent(
3236
model=OpenAIChat(id="gpt-4o"),
3337
# Agentic RAG is enabled by default when `knowledge` is provided to the Agent.

libs/agno/agno/agent/agent.py

Lines changed: 32 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -893,7 +893,7 @@ def _run_stream(
893893
):
894894
yield event
895895
else:
896-
from agno.utils.events import RunResponseContentEvent
896+
from agno.run.response import IntermediateRunResponseContentEvent, RunResponseContentEvent
897897

898898
for event in self._handle_model_response_stream(
899899
run_response=run_response,
@@ -903,7 +903,10 @@ def _run_stream(
903903
):
904904
if isinstance(event, RunResponseContentEvent):
905905
if stream_intermediate_steps:
906-
yield event
906+
yield IntermediateRunResponseContentEvent(
907+
content=event.content,
908+
content_type=event.content_type,
909+
)
907910
else:
908911
yield event
909912

@@ -1331,7 +1334,7 @@ async def _arun_stream(
13311334
):
13321335
yield event
13331336
else:
1334-
from agno.utils.events import RunResponseContentEvent
1337+
from agno.run.response import IntermediateRunResponseContentEvent, RunResponseContentEvent
13351338

13361339
async for event in self._ahandle_model_response_stream(
13371340
run_response=run_response,
@@ -1341,7 +1344,10 @@ async def _arun_stream(
13411344
):
13421345
if isinstance(event, RunResponseContentEvent):
13431346
if stream_intermediate_steps:
1344-
yield event
1347+
yield IntermediateRunResponseContentEvent(
1348+
content=event.content,
1349+
content_type=event.content_type,
1350+
)
13451351
else:
13461352
yield event
13471353

@@ -4973,9 +4979,26 @@ def get_run_messages(
49734979

49744980
run_messages.messages += history_copy
49754981

4976-
# 4.Add user message to run_messages
4982+
# 4. Add messages to run_messages if provided
4983+
if messages is not None and len(messages) > 0:
4984+
for _m in messages:
4985+
if isinstance(_m, Message):
4986+
run_messages.messages.append(_m)
4987+
if run_messages.extra_messages is None:
4988+
run_messages.extra_messages = []
4989+
run_messages.extra_messages.append(_m)
4990+
elif isinstance(_m, dict):
4991+
try:
4992+
run_messages.messages.append(Message.model_validate(_m))
4993+
if run_messages.extra_messages is None:
4994+
run_messages.extra_messages = []
4995+
run_messages.extra_messages.append(Message.model_validate(_m))
4996+
except Exception as e:
4997+
log_warning(f"Failed to validate message: {e}")
4998+
4999+
# 5. Add user message to run_messages
49775000
user_message: Optional[Message] = None
4978-
# 4.1 Build user message if message is None, str or list
5001+
# 5.1 Build user message if message is None, str or list
49795002
if message is None or isinstance(message, str) or isinstance(message, list):
49805003
user_message = self.get_user_message(
49815004
message=message,
@@ -4986,16 +5009,16 @@ def get_run_messages(
49865009
knowledge_filters=knowledge_filters,
49875010
**kwargs,
49885011
)
4989-
# 4.2 If message is provided as a Message, use it directly
5012+
# 5.2 If message is provided as a Message, use it directly
49905013
elif isinstance(message, Message):
49915014
user_message = message
4992-
# 4.3 If message is provided as a dict, try to validate it as a Message
5015+
# 5.3 If message is provided as a dict, try to validate it as a Message
49935016
elif isinstance(message, dict):
49945017
try:
49955018
user_message = Message.model_validate(message)
49965019
except Exception as e:
49975020
log_warning(f"Failed to validate message: {e}")
4998-
# 4.4 If message is provided as a BaseModel, convert it to a Message
5021+
# 5.4 If message is provided as a BaseModel, convert it to a Message
49995022
elif isinstance(message, BaseModel):
50005023
try:
50015024
# Create a user message with the BaseModel content
@@ -5008,23 +5031,6 @@ def get_run_messages(
50085031
run_messages.user_message = user_message
50095032
run_messages.messages.append(user_message)
50105033

5011-
# 5. Add messages to run_messages if provided
5012-
if messages is not None and len(messages) > 0:
5013-
for _m in messages:
5014-
if isinstance(_m, Message):
5015-
run_messages.messages.append(_m)
5016-
if run_messages.extra_messages is None:
5017-
run_messages.extra_messages = []
5018-
run_messages.extra_messages.append(_m)
5019-
elif isinstance(_m, dict):
5020-
try:
5021-
run_messages.messages.append(Message.model_validate(_m))
5022-
if run_messages.extra_messages is None:
5023-
run_messages.extra_messages = []
5024-
run_messages.extra_messages.append(Message.model_validate(_m))
5025-
except Exception as e:
5026-
log_warning(f"Failed to validate message: {e}")
5027-
50285034
return run_messages
50295035

50305036
def get_continue_run_messages(

libs/agno/agno/run/response.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ class RunEvent(str, Enum):
1717

1818
run_started = "RunStarted"
1919
run_response_content = "RunResponseContent"
20+
run_intermediate_response_content = "RunIntermediateResponseContent"
2021
run_completed = "RunCompleted"
2122
run_error = "RunError"
2223
run_cancelled = "RunCancelled"
@@ -92,6 +93,13 @@ class RunResponseContentEvent(BaseAgentRunResponseEvent):
9293
extra_data: Optional[RunResponseExtraData] = None
9394

9495

96+
@dataclass
97+
class IntermediateRunResponseContentEvent(BaseAgentRunResponseEvent):
98+
event: str = RunEvent.run_intermediate_response_content.value
99+
content: Optional[Any] = None
100+
content_type: str = "str"
101+
102+
95103
@dataclass
96104
class RunResponseCompletedEvent(BaseAgentRunResponseEvent):
97105
event: str = RunEvent.run_completed.value
@@ -207,6 +215,7 @@ class OutputModelResponseCompletedEvent(BaseAgentRunResponseEvent):
207215
RunResponseEvent = Union[
208216
RunResponseStartedEvent,
209217
RunResponseContentEvent,
218+
IntermediateRunResponseContentEvent,
210219
RunResponseCompletedEvent,
211220
RunResponseErrorEvent,
212221
RunResponseCancelledEvent,
@@ -230,6 +239,7 @@ class OutputModelResponseCompletedEvent(BaseAgentRunResponseEvent):
230239
RUN_EVENT_TYPE_REGISTRY = {
231240
RunEvent.run_started.value: RunResponseStartedEvent,
232241
RunEvent.run_response_content.value: RunResponseContentEvent,
242+
RunEvent.run_intermediate_response_content.value: IntermediateRunResponseContentEvent,
233243
RunEvent.run_completed.value: RunResponseCompletedEvent,
234244
RunEvent.run_error.value: RunResponseErrorEvent,
235245
RunEvent.run_cancelled.value: RunResponseCancelledEvent,

libs/agno/agno/run/team.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ class TeamRunEvent(str, Enum):
1717

1818
run_started = "TeamRunStarted"
1919
run_response_content = "TeamRunResponseContent"
20+
run_intermediate_response_content = "TeamRunIntermediateResponseContent"
2021
run_completed = "TeamRunCompleted"
2122
run_error = "TeamRunError"
2223
run_cancelled = "TeamRunCancelled"
@@ -94,6 +95,13 @@ class RunResponseContentEvent(BaseTeamRunResponseEvent):
9495
extra_data: Optional[RunResponseExtraData] = None
9596

9697

98+
@dataclass
99+
class IntermediateRunResponseContentEvent(BaseTeamRunResponseEvent):
100+
event: str = TeamRunEvent.run_intermediate_response_content.value
101+
content: Optional[Any] = None
102+
content_type: str = "str"
103+
104+
97105
@dataclass
98106
class RunResponseCompletedEvent(BaseTeamRunResponseEvent):
99107
event: str = TeamRunEvent.run_completed.value
@@ -191,6 +199,7 @@ class OutputModelResponseCompletedEvent(BaseTeamRunResponseEvent):
191199
TeamRunResponseEvent = Union[
192200
RunResponseStartedEvent,
193201
RunResponseContentEvent,
202+
IntermediateRunResponseContentEvent,
194203
RunResponseCompletedEvent,
195204
RunResponseErrorEvent,
196205
RunResponseCancelledEvent,
@@ -211,6 +220,7 @@ class OutputModelResponseCompletedEvent(BaseTeamRunResponseEvent):
211220
TEAM_RUN_EVENT_TYPE_REGISTRY = {
212221
TeamRunEvent.run_started.value: RunResponseStartedEvent,
213222
TeamRunEvent.run_response_content.value: RunResponseContentEvent,
223+
TeamRunEvent.run_intermediate_response_content.value: IntermediateRunResponseContentEvent,
214224
TeamRunEvent.run_completed.value: RunResponseCompletedEvent,
215225
TeamRunEvent.run_error.value: RunResponseErrorEvent,
216226
TeamRunEvent.run_cancelled.value: RunResponseCancelledEvent,

libs/agno/agno/team/team.py

Lines changed: 24 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1110,16 +1110,21 @@ def _run_stream(
11101110
response_format=response_format,
11111111
stream_intermediate_steps=stream_intermediate_steps,
11121112
):
1113-
from agno.run.team import RunResponseContentEvent
1113+
from agno.run.team import IntermediateRunResponseContentEvent, RunResponseContentEvent
11141114

11151115
if isinstance(event, RunResponseContentEvent):
11161116
if stream_intermediate_steps:
1117-
yield event
1117+
yield IntermediateRunResponseContentEvent(
1118+
content=event.content,
1119+
content_type=event.content_type,
1120+
)
11181121
else:
11191122
yield event
11201123

11211124
yield from self._generate_response_with_output_model_stream(
1122-
run_response=run_response, run_messages=run_messages
1125+
run_response=run_response,
1126+
run_messages=run_messages,
1127+
stream_intermediate_steps=stream_intermediate_steps,
11231128
)
11241129

11251130
# If a parser model is provided, structure the response separately
@@ -1519,19 +1524,28 @@ async def _arun_stream(
15191524
):
15201525
yield event
15211526
else:
1522-
from agno.run.team import RunResponseContentEvent
1523-
1524-
async for event in self._agenerate_response_with_output_model_stream(
1527+
async for event in self._ahandle_model_response_stream(
15251528
run_response=run_response,
15261529
run_messages=run_messages,
1530+
response_format=response_format,
15271531
stream_intermediate_steps=stream_intermediate_steps,
15281532
):
1533+
from agno.run.team import IntermediateRunResponseContentEvent, RunResponseContentEvent
1534+
15291535
if isinstance(event, RunResponseContentEvent):
15301536
if stream_intermediate_steps:
1531-
yield event
1537+
yield IntermediateRunResponseContentEvent(
1538+
content=event.content,
1539+
content_type=event.content_type,
1540+
)
15321541
else:
15331542
yield event
15341543

1544+
async for event in self._agenerate_response_with_output_model_stream(
1545+
run_response=run_response,
1546+
run_messages=run_messages,
1547+
stream_intermediate_steps=stream_intermediate_steps,
1548+
):
15351549
yield event
15361550

15371551
# If a parser model is provided, structure the response separately
@@ -2446,10 +2460,9 @@ def _parse_response_with_output_model(self, model_response: ModelResponse, run_m
24462460
model_response.content = output_model_response.content
24472461

24482462
def _generate_response_with_output_model_stream(
2449-
self, run_response: TeamRunResponse, run_messages: RunMessages, stream_intermediate_steps: bool = True
2463+
self, run_response: TeamRunResponse, run_messages: RunMessages, stream_intermediate_steps: bool = False
24502464
):
24512465
"""Parse the model response using the output model stream."""
2452-
24532466
from agno.utils.events import (
24542467
create_team_output_model_response_completed_event,
24552468
create_team_output_model_response_started_event,
@@ -2497,7 +2510,7 @@ async def _agenerate_response_with_output_model(
24972510
model_response.content = output_model_response.content
24982511

24992512
async def _agenerate_response_with_output_model_stream(
2500-
self, run_response: TeamRunResponse, run_messages: RunMessages, stream_intermediate_steps: bool = True
2513+
self, run_response: TeamRunResponse, run_messages: RunMessages, stream_intermediate_steps: bool = False
25012514
):
25022515
"""Parse the model response using the output model stream."""
25032516
from agno.utils.events import (
@@ -2514,9 +2527,7 @@ async def _agenerate_response_with_output_model_stream(
25142527
messages_for_output_model = self.get_messages_for_output_model(run_messages.messages)
25152528
model_response = ModelResponse(content="")
25162529

2517-
model_response_stream = self.output_model.aresponse_stream(messages=messages_for_output_model)
2518-
2519-
async for model_response_event in model_response_stream:
2530+
async for model_response_event in self.output_model.aresponse_stream(messages=messages_for_output_model):
25202531
for event in self._handle_model_response_chunk(
25212532
run_response=run_response,
25222533
full_model_response=model_response,

0 commit comments

Comments
 (0)