Spaces:
Sleeping
Sleeping
Update src/streamlit_app.py
Browse files- src/streamlit_app.py +80 -23
src/streamlit_app.py
CHANGED
@@ -6,45 +6,102 @@ from google.adk.tools import google_search
|
|
6 |
from google.genai import types
|
7 |
from dotenv import load_dotenv
|
8 |
|
9 |
-
|
10 |
-
|
11 |
-
|
12 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
13 |
@st.cache_resource
|
14 |
def init_adk():
|
15 |
-
ss = InMemorySessionService()
|
16 |
-
sid = st.session_state.get("adk_session_id") or f"session_{int(time.time())}_{os.urandom(4).hex()}"
|
17 |
-
|
18 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
19 |
return r, sid
|
20 |
|
|
|
21 |
async def run_adk(r, sid, q):
|
22 |
try:
|
23 |
-
async for e in r.run_async(
|
24 |
-
|
25 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
26 |
return "[No response]"
|
27 |
|
|
|
28 |
def main():
|
29 |
-
st.set_page_config(page_title="Search", page_icon="π", layout="wide")
|
|
|
30 |
st.markdown(
|
31 |
-
|
32 |
-
|
|
|
|
|
33 |
)
|
34 |
-
|
35 |
-
|
36 |
-
|
37 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
38 |
for msg in st.session_state.msgs:
|
39 |
-
with st.chat_message(msg["role"]):
|
|
|
|
|
|
|
40 |
if prompt := st.chat_input("Ask..."):
|
41 |
-
st.session_state.msgs.append({"role": "user", "content": prompt})
|
42 |
-
with st.chat_message("user"):
|
|
|
|
|
43 |
with st.chat_message("assistant"):
|
44 |
placeholder = st.empty()
|
45 |
-
with st.spinner("Searching..."):
|
|
|
|
|
46 |
st.session_state.msgs.append({"role": "assistant", "content": response})
|
47 |
-
|
|
|
|
|
|
|
|
|
48 |
st.sidebar.caption(f"**Model**: **{MODEL}**")
|
49 |
|
50 |
-
|
|
|
|
|
|
6 |
from google.genai import types
|
7 |
from dotenv import load_dotenv
|
8 |
|
9 |
+
# Load environment variables
|
10 |
+
load_dotenv()
|
11 |
+
logging.basicConfig(level=logging.ERROR)
|
12 |
|
13 |
+
MODEL = "gemini-2.0-flash-lite"
|
14 |
+
APP_NAME = "search_assistant_app"
|
15 |
+
USER_ID = "streamlit_user_search"
|
16 |
+
|
17 |
+
# Define agent
|
18 |
+
agent = Agent(
|
19 |
+
name="search_assistant",
|
20 |
+
model=MODEL,
|
21 |
+
instruction="You are a helpful assistant. Answer user questions using Google Search when needed.",
|
22 |
+
description="An assistant that can search the web.",
|
23 |
+
tools=[google_search]
|
24 |
+
)
|
25 |
+
|
26 |
+
# Initialize ADK runner + session
|
27 |
@st.cache_resource
|
28 |
def init_adk():
|
29 |
+
ss = InMemorySessionService()
|
30 |
+
sid = st.session_state.get("adk_session_id") or f"session_{int(time.time())}_{os.urandom(4).hex()}"
|
31 |
+
st.session_state["adk_session_id"] = sid
|
32 |
+
|
33 |
+
# Create session BEFORE runner
|
34 |
+
try:
|
35 |
+
ss.create_session(app_name=APP_NAME, user_id=USER_ID, session_id=sid, state={})
|
36 |
+
except Exception:
|
37 |
+
pass # ignore if already created
|
38 |
+
|
39 |
+
r = Runner(agent=agent, app_name=APP_NAME, session_service=ss)
|
40 |
return r, sid
|
41 |
|
42 |
+
# Run ADK asynchronously
|
43 |
async def run_adk(r, sid, q):
|
44 |
try:
|
45 |
+
async for e in r.run_async(
|
46 |
+
user_id=USER_ID,
|
47 |
+
session_id=sid,
|
48 |
+
new_message=types.Content(role="user", parts=[types.Part(text=q)])
|
49 |
+
):
|
50 |
+
if e.is_final_response() and e.content and e.content.parts:
|
51 |
+
return e.content.parts[0].text
|
52 |
+
except Exception as err:
|
53 |
+
return f"Error: {err}"
|
54 |
return "[No response]"
|
55 |
|
56 |
+
# Streamlit UI
|
57 |
def main():
|
58 |
+
st.set_page_config(page_title="Search", page_icon="π", layout="wide")
|
59 |
+
|
60 |
st.markdown(
|
61 |
+
f'<h1><img src="https://upload.wikimedia.org/wikipedia/commons/thumb/2/2f/Google_2015_logo.svg/1200px-Google_2015_logo.svg.png" width="135"/> '
|
62 |
+
f'Agent Development Kit '
|
63 |
+
f'<img src="https://images.seeklogo.com/logo-png/44/2/streamlit-logo-png_seeklogo-441815.png" width="60"/></h1>',
|
64 |
+
unsafe_allow_html=True
|
65 |
)
|
66 |
+
|
67 |
+
if not os.environ.get("GOOGLE_API_KEY"):
|
68 |
+
st.error("API Key missing!")
|
69 |
+
st.stop()
|
70 |
+
|
71 |
+
try:
|
72 |
+
r, sid = init_adk()
|
73 |
+
st.sidebar.success(f"β
ADK Connected (Session: ...{sid[-8:]})")
|
74 |
+
except Exception as e:
|
75 |
+
st.error(f"ADK failed: {e}", icon="β")
|
76 |
+
st.stop()
|
77 |
+
|
78 |
+
if "msgs" not in st.session_state:
|
79 |
+
st.session_state.msgs = []
|
80 |
+
|
81 |
+
# Display past messages
|
82 |
for msg in st.session_state.msgs:
|
83 |
+
with st.chat_message(msg["role"]):
|
84 |
+
st.markdown(msg["content"])
|
85 |
+
|
86 |
+
# Chat input
|
87 |
if prompt := st.chat_input("Ask..."):
|
88 |
+
st.session_state.msgs.append({"role": "user", "content": prompt})
|
89 |
+
with st.chat_message("user"):
|
90 |
+
st.markdown(prompt)
|
91 |
+
|
92 |
with st.chat_message("assistant"):
|
93 |
placeholder = st.empty()
|
94 |
+
with st.spinner("Searching..."):
|
95 |
+
response = asyncio.run(run_adk(r, sid, prompt))
|
96 |
+
placeholder.markdown(response)
|
97 |
st.session_state.msgs.append({"role": "assistant", "content": response})
|
98 |
+
|
99 |
+
st.sidebar.image(
|
100 |
+
"https://cdn-images-1.medium.com/v2/resize:fill:1600:480/gravity:fp:0.5:0.4/1*A4-k_sI5kmrphjS4tJ_rpA.png",
|
101 |
+
use_container_width=True
|
102 |
+
)
|
103 |
st.sidebar.caption(f"**Model**: **{MODEL}**")
|
104 |
|
105 |
+
|
106 |
+
if __name__ == "__main__":
|
107 |
+
main()
|