Skip to content

Commit dbaac46

Browse files
dirkbrndkausmeows
andauthored
[feat] Add current_user_id and current_session_id (#3152)
## Summary Keep track of the current user ID and current session ID to use in tools ## Type of change - [ ] Bug fix - [x] New feature - [ ] Breaking change - [ ] Improvement - [ ] Model update - [ ] Other: --- ## Checklist - [ ] Code complies with style guidelines - [ ] Ran format/validation scripts (`./scripts/format.sh` and `./scripts/validate.sh`) - [ ] Self-review completed - [ ] Documentation updated (comments, docstrings) - [ ] Examples and guides: Relevant cookbook examples have been included or updated (if applicable) - [ ] Tested in clean environment - [ ] Tests added/updated (if applicable) --- ## Additional Notes Add any important context (deployment instructions, screenshots, security considerations, etc.) --------- Co-authored-by: Kaustubh <shuklakaustubh84@gmail.com>
1 parent 074368d commit dbaac46

File tree

4 files changed

+159
-11
lines changed

4 files changed

+159
-11
lines changed
Lines changed: 123 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,123 @@
1+
"""
2+
This example demonstrates how to maintain state for each user in a multi-user environment.
3+
4+
The shopping list is stored in a dictionary, organized by user ID and session ID.
5+
6+
Agno automatically creates the "current_user_id" and "current_session_id" variables in the session state.
7+
8+
You can access these variables in your functions using the `agent.session_state` dictionary.
9+
"""
10+
11+
import json
12+
13+
from agno.agent import Agent
14+
from agno.models.openai import OpenAIChat
15+
from agno.utils.log import log_info
16+
17+
# In-memory database to store user shopping lists
18+
# Organized by user ID and session ID
19+
shopping_list = {}
20+
21+
22+
def add_item(agent: Agent, item: str) -> str:
23+
"""Add an item to the current user's shopping list."""
24+
current_user_id = agent.session_state["current_user_id"]
25+
current_session_id = agent.session_state["current_session_id"]
26+
shopping_list.setdefault(current_user_id, {}).setdefault(
27+
current_session_id, []
28+
).append(item)
29+
return f"Item {item} added to the shopping list"
30+
31+
32+
def remove_item(agent: Agent, item: str) -> str:
33+
"""Remove an item from the current user's shopping list."""
34+
current_user_id = agent.session_state["current_user_id"]
35+
current_session_id = agent.session_state["current_session_id"]
36+
37+
if (
38+
current_user_id not in shopping_list
39+
or current_session_id not in shopping_list[current_user_id]
40+
):
41+
return f"No shopping list found for user {current_user_id} and session {current_session_id}"
42+
43+
if item not in shopping_list[current_user_id][current_session_id]:
44+
return f"Item '{item}' not found in the shopping list for user {current_user_id} and session {current_session_id}"
45+
46+
shopping_list[current_user_id][current_session_id].remove(item)
47+
return f"Item {item} removed from the shopping list"
48+
49+
50+
def get_shopping_list(agent: Agent) -> str:
51+
"""Get the current user's shopping list."""
52+
current_user_id = agent.session_state["current_user_id"]
53+
current_session_id = agent.session_state["current_session_id"]
54+
return f"Shopping list for user {current_user_id} and session {current_session_id}: \n{json.dumps(shopping_list[current_user_id][current_session_id], indent=2)}"
55+
56+
57+
# Create an Agent that maintains state
58+
agent = Agent(
59+
model=OpenAIChat(id="gpt-4o-mini"),
60+
tools=[add_item, remove_item, get_shopping_list],
61+
# Reference the in-memory database
62+
instructions=[
63+
"Current User ID: {current_user_id}",
64+
"Current Session ID: {current_session_id}",
65+
],
66+
# Important: Add the state in the instructions
67+
add_state_in_messages=True,
68+
markdown=True,
69+
)
70+
71+
user_id_1 = "john_doe"
72+
user_id_2 = "mark_smith"
73+
user_id_3 = "carmen_sandiago"
74+
75+
# Example usage
76+
agent.print_response(
77+
"Add milk, eggs, and bread to the shopping list",
78+
stream=True,
79+
user_id=user_id_1,
80+
session_id="user_1_session_1",
81+
)
82+
agent.print_response(
83+
"Add tacos to the shopping list",
84+
stream=True,
85+
user_id=user_id_2,
86+
session_id="user_2_session_1",
87+
)
88+
agent.print_response(
89+
"Add apples and grapesto the shopping list",
90+
stream=True,
91+
user_id=user_id_3,
92+
session_id="user_3_session_1",
93+
)
94+
agent.print_response(
95+
"Remove milk from the shopping list",
96+
stream=True,
97+
user_id=user_id_1,
98+
session_id="user_1_session_1",
99+
)
100+
agent.print_response(
101+
"Add minced beef to the shopping list",
102+
stream=True,
103+
user_id=user_id_2,
104+
session_id="user_2_session_1",
105+
)
106+
107+
# What is on Mark Smith's shopping list?
108+
agent.print_response(
109+
"What is on Mark Smith's shopping list?",
110+
stream=True,
111+
user_id=user_id_2,
112+
session_id="user_2_session_1",
113+
)
114+
115+
# New session, so new shopping list
116+
agent.print_response(
117+
"Add chicken and soup to my list.",
118+
stream=True,
119+
user_id=user_id_2,
120+
session_id="user_3_session_2",
121+
)
122+
123+
print(f"Final shopping lists: \n{json.dumps(shopping_list, indent=2)}")

cookbook/observability/langfuse_via_openlit.py

Lines changed: 18 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -2,47 +2,54 @@
22
This example shows how to use langfuse via OpenLIT to trace model calls.
33
44
1. Install dependencies: pip install openai langfuse openlit opentelemetry-sdk opentelemetry-exporter-otlp
5-
2. Set your Langfuse API key as an environment variables:
5+
2. Set your Langfuse API key as an environment variables:
66
- export LANGFUSE_PUBLIC_KEY=<your-key>
77
- export LANGFUSE_SECRET_KEY=<your-key>
88
"""
99

1010
import base64
1111
import os
12+
1213
from agno.agent import Agent
1314
from agno.models.openai import OpenAIChat
1415
from agno.tools.duckduckgo import DuckDuckGoTools
1516

16-
LANGFUSE_AUTH = base64.b64encode(f"{os.getenv('LANGFUSE_PUBLIC_KEY')}:{os.getenv('LANGFUSE_SECRET_KEY')}".encode()).decode()
17+
LANGFUSE_AUTH = base64.b64encode(
18+
f"{os.getenv('LANGFUSE_PUBLIC_KEY')}:{os.getenv('LANGFUSE_SECRET_KEY')}".encode()
19+
).decode()
1720

18-
os.environ["OTEL_EXPORTER_OTLP_ENDPOINT"]="https://us.cloud.langfuse.com/api/public/otel" # 🇺🇸 US data region
21+
os.environ["OTEL_EXPORTER_OTLP_ENDPOINT"] = (
22+
"https://us.cloud.langfuse.com/api/public/otel" # 🇺🇸 US data region
23+
)
1924
# os.environ["OTEL_EXPORTER_OTLP_ENDPOINT"]="https://cloud.langfuse.com/api/public/otel" # 🇪🇺 EU data region
2025
# os.environ["OTEL_EXPORTER_OTLP_ENDPOINT"]="http://localhost:3000/api/public/otel" # 🏠 Local deployment (>= v3.22.0)
21-
22-
os.environ["OTEL_EXPORTER_OTLP_HEADERS"]=f"Authorization=Basic {LANGFUSE_AUTH}"
2326

24-
from opentelemetry.sdk.trace import TracerProvider
27+
os.environ["OTEL_EXPORTER_OTLP_HEADERS"] = f"Authorization=Basic {LANGFUSE_AUTH}"
28+
2529
from opentelemetry.exporter.otlp.proto.http.trace_exporter import OTLPSpanExporter
30+
from opentelemetry.sdk.trace import TracerProvider
2631
from opentelemetry.sdk.trace.export import SimpleSpanProcessor
27-
32+
2833
trace_provider = TracerProvider()
2934
trace_provider.add_span_processor(SimpleSpanProcessor(OTLPSpanExporter()))
30-
35+
3136
# Sets the global default tracer provider
3237
from opentelemetry import trace
38+
3339
trace.set_tracer_provider(trace_provider)
34-
40+
3541
# Creates a tracer from the global tracer provider
3642
tracer = trace.get_tracer(__name__)
3743

3844
import openlit
45+
3946
# Initialize OpenLIT instrumentation. The disable_batch flag is set to true to process traces immediately.
4047
openlit.init(tracer=tracer, disable_batch=True)
4148

4249
agent = Agent(
43-
model=OpenAIChat(id="gpt-4o-mini"),
50+
model=OpenAIChat(id="gpt-4o-mini"),
4451
tools=[DuckDuckGoTools()],
45-
markdown=True,
52+
markdown=True,
4653
debug_mode=True,
4754
)
4855

libs/agno/agno/agent/agent.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1089,6 +1089,8 @@ def run(
10891089

10901090
session_id = cast(str, session_id)
10911091

1092+
self._initialize_session_state(user_id=user_id, session_id=session_id)
1093+
10921094
log_debug(f"Session ID: {session_id}", center=True)
10931095

10941096
last_exception = None
@@ -1698,6 +1700,8 @@ async def arun(
16981700

16991701
session_id = cast(str, session_id)
17001702

1703+
self._initialize_session_state(user_id=user_id, session_id=session_id)
1704+
17011705
log_debug(f"Session ID: {session_id}", center=True)
17021706

17031707
last_exception = None
@@ -1849,6 +1853,11 @@ def create_run_response(
18491853
rr.created_at = created_at
18501854
return rr
18511855

1856+
def _initialize_session_state(self, user_id: Optional[str] = None, session_id: Optional[str] = None) -> None:
1857+
self.session_state = self.session_state or {}
1858+
self.session_state["current_user_id"] = user_id
1859+
self.session_state["current_session_id"] = session_id
1860+
18521861
def _make_memories_and_summaries(
18531862
self,
18541863
run_messages: RunMessages,

libs/agno/agno/team/team.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -567,6 +567,8 @@ def run(
567567

568568
session_id = cast(str, session_id)
569569

570+
self._initialize_session_state(user_id=user_id, session_id=session_id)
571+
570572
log_debug(f"Session ID: {session_id}", center=True)
571573

572574
self.initialize_team(session_id=session_id)
@@ -1313,6 +1315,8 @@ async def arun(
13131315

13141316
session_id = cast(str, session_id)
13151317

1318+
self._initialize_session_state(user_id=user_id, session_id=session_id)
1319+
13161320
log_debug(f"Session ID: {session_id}", center=True)
13171321

13181322
self.initialize_team(session_id=session_id)
@@ -1990,6 +1994,11 @@ async def _arun_stream(
19901994

19911995
log_debug(f"Team Run End: {self.run_id}", center=True, symbol="*")
19921996

1997+
def _initialize_session_state(self, user_id: Optional[str] = None, session_id: Optional[str] = None) -> None:
1998+
self.session_state = self.session_state or {}
1999+
self.session_state["current_user_id"] = user_id
2000+
self.session_state["current_session_id"] = session_id
2001+
19932002
def _make_memories_and_summaries(
19942003
self, run_messages: RunMessages, session_id: str, user_id: Optional[str] = None
19952004
) -> None:

0 commit comments

Comments
 (0)