Skip to content

Commit 886ab76

Browse files
committed
Adding assistant secretary agent python code + requirements + read me file
1 parent 0c5696a commit 886ab76

File tree

7 files changed

+1441
-0
lines changed

7 files changed

+1441
-0
lines changed

ai/gen-ai-agents/assistant.py

Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
"""
2+
By Omar Salem
3+
assistant.py - AI Assistant Chatbot (Dynamic Routing).
4+
"""
5+
6+
from state import State
7+
from router import Router
8+
from tools import (
9+
handle_fetch_gmail,
10+
handle_send_email,
11+
handle_ai_agent_query,
12+
handle_select_email,
13+
handle_schedule_email,
14+
handle_llm_query,
15+
handle_weather_query,
16+
handle_calculator,
17+
# handle_generate_reply_with_weather,
18+
handle_generate_reply_with_user_message_and_ai_response,
19+
handle_generate_reply_with_user_message_only,
20+
handle_book_meeting
21+
)
22+
import json
23+
24+
# initialize router
25+
router = Router()
26+
27+
# initialize State
28+
state: State = {
29+
"input": "",
30+
"decisions": [],
31+
"output": "",
32+
"emails": [],
33+
"selected_email": None,
34+
"recipient": "",
35+
"subject": "",
36+
"body": "",
37+
"ai_response": "",
38+
"citations": [],
39+
}
40+
41+
# dynamically map tools
42+
TOOLS = {
43+
"fetch_and_summarize": handle_fetch_gmail,
44+
"send_email": handle_send_email,
45+
"ai_agent": handle_ai_agent_query,
46+
"select_email": handle_select_email,
47+
"schedule_email": handle_schedule_email,
48+
"llm_query": handle_llm_query,
49+
"weather_query": handle_weather_query,
50+
"calculator": handle_calculator,
51+
"generate_reply_with_user_message_only": handle_generate_reply_with_user_message_only,
52+
"generate_reply_with_user_message_and_ai_response": handle_generate_reply_with_user_message_and_ai_response,
53+
"book_meeting": handle_book_meeting,
54+
}
55+
56+
57+
def chatbot():
58+
"""Interactive Chatbot for AI Assistant"""
59+
print("\n **AI Assistant** - Type 'exit' to quit.\n")
60+
61+
while True:
62+
# get user input
63+
user_input = input("📝 You: ").strip()
64+
if user_input.lower() in ["exit", "quit"]:
65+
print("\n👋 Exiting. Have a great day!")
66+
break
67+
68+
# update State
69+
state["input"] = user_input
70+
71+
# dynamic routing assignment
72+
routing_result = router.route(state)
73+
state["decisions"] = routing_result.get("decisions", [])
74+
75+
print(f"\n🤖 **Routing Decisions:** `{state['decisions']}`\n")
76+
77+
# store responses from multiple tools
78+
responses = []
79+
80+
#dynamically execute tools
81+
for decision in state["decisions"]:
82+
tool = TOOLS.get(decision)
83+
if tool:
84+
result = tool(state) # execute tool picked dynamically
85+
responses.append(result["output"])
86+
else:
87+
responses.append(f"❌ Invalid decision: `{decision}`.")
88+
89+
# convert lists to formatted JSON strings before joining
90+
state["output"] = "\n\n".join(
91+
[json.dumps(resp, indent=2) if isinstance(resp, list) else str(resp) for resp in responses]
92+
)
93+
94+
# display Output
95+
print(f"\n✅ **Response:**\n{state['output']}\n")
96+
97+
98+
# run the Chatbot
99+
if __name__ == "__main__":
100+
chatbot()

ai/gen-ai-agents/frontend.py

Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
import streamlit as st
2+
import json
3+
import time
4+
from assistant import TOOLS, router, state
5+
6+
# ==============================
7+
# STREAMLIT UI CONFIGURATION
8+
# ==============================
9+
st.set_page_config(page_title="OCI Assistant Chatbot", layout="wide")
10+
11+
st.markdown(
12+
"<h1 style='text-align: center;'>OCI Assistant Chatbot</h1>",
13+
unsafe_allow_html=True
14+
)
15+
st.write("Manage your emails, schedule meetings, check the weather, and more...")
16+
17+
# ==============================
18+
# INITIALIZE SESSION STATE
19+
# ==============================
20+
if "chat_history" not in st.session_state:
21+
st.session_state.chat_history = []
22+
23+
if "selected_email" not in st.session_state:
24+
st.session_state.selected_email = None
25+
26+
if "latest_response" not in st.session_state:
27+
st.session_state.latest_response = ""
28+
29+
# ==============================
30+
# CHATBOT INTERFACE
31+
# ==============================
32+
33+
# Display chat history
34+
for chat in st.session_state.chat_history:
35+
with st.chat_message("user"):
36+
st.markdown(chat["user"])
37+
with st.chat_message("assistant"):
38+
st.markdown(chat["bot"])
39+
40+
# User input field
41+
user_input = st.text_input("Type your message here...", key="user_input")
42+
43+
# Process user message
44+
if st.button("Send"):
45+
if user_input:
46+
# Display steps
47+
step_placeholder = st.empty() # This will dynamically update
48+
step_placeholder.markdown("🟢 **Step 1:** Capturing user input...")
49+
50+
# Update state with user input
51+
state["input"] = user_input
52+
53+
# Display second step
54+
step_placeholder.markdown("🟢 **Step 2:** Identifying the correct tool...")
55+
56+
# Show spinner while routing
57+
with st.spinner("Processing..."):
58+
time.sleep(1) # Simulating delay
59+
60+
# Route input to the correct function
61+
routing_result = router.route(state)
62+
state["decisions"] = routing_result.get("decisions", [])
63+
64+
# Show detected decisions
65+
step_placeholder.markdown(f"🟢 **Step 3:** Decision made → `{state['decisions']}`")
66+
67+
# Execute tool functions
68+
responses = []
69+
for i, decision in enumerate(state["decisions"], start=1):
70+
step_placeholder.markdown(f"🟢 **Step 4.{i}:** Executing `{decision}`...")
71+
72+
tool = TOOLS.get(decision)
73+
if tool:
74+
with st.spinner(f"Running `{decision}`..."):
75+
time.sleep(1) # Simulate processing time
76+
result = tool(state)
77+
responses.append(result["output"])
78+
else:
79+
responses.append(f"❌ Invalid decision: `{decision}`.")
80+
81+
# Finalize response
82+
step_placeholder.markdown("✅ **Step 5:** Formatting response...")
83+
84+
# Store response
85+
state["output"] = "\n\n".join(
86+
[json.dumps(resp, indent=2) if isinstance(resp, list) else str(resp) for resp in responses]
87+
)
88+
89+
# Update chat history
90+
st.session_state.chat_history.append({"user": user_input, "bot": state["output"]})
91+
92+
# Store latest response
93+
st.session_state.latest_response = state["output"]
94+
95+
# Refresh UI
96+
st.rerun()
Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
aiohappyeyeballs==2.4.3
2+
aiohttp==3.11.7
3+
aiosignal==1.3.1
4+
altair==5.5.0
5+
annotated-types==0.7.0
6+
anyio==4.8.0
7+
asttokens==3.0.0
8+
attrs==24.2.0
9+
blinker==1.9.0
10+
cachetools==5.5.0
11+
certifi==2024.12.14
12+
cffi==1.17.1
13+
charset-normalizer==3.4.1
14+
circuitbreaker==2.0.0
15+
click==8.1.7
16+
cryptography==43.0.3
17+
dataclasses-json==0.6.7
18+
decorator==5.1.1
19+
executing==2.2.0
20+
frozenlist==1.5.0
21+
gitdb==4.0.11
22+
GitPython==3.1.43
23+
h11==0.14.0
24+
httpcore==1.0.7
25+
httpx==0.28.1
26+
httpx-sse==0.4.0
27+
idna==3.10
28+
ipython==8.31.0
29+
jedi==0.19.2
30+
Jinja2==3.1.4
31+
jsonpatch==1.33
32+
jsonpointer==3.0.0
33+
jsonschema==4.23.0
34+
jsonschema-specifications==2024.10.1
35+
langchain==0.3.14
36+
langchain-community==0.3.14
37+
langchain-core==0.3.29
38+
langchain-experimental==0.3.4
39+
langchain-text-splitters==0.3.5
40+
langgraph==0.2.62
41+
langgraph-checkpoint==2.0.8
42+
langgraph-sdk==0.1.51
43+
langsmith==0.2.11
44+
markdown-it-py==3.0.0
45+
MarkupSafe==3.0.2
46+
marshmallow==3.23.1
47+
matplotlib-inline==0.1.7
48+
mdurl==0.1.2
49+
msgpack==1.1.0
50+
multidict==6.1.0
51+
mypy-extensions==1.0.0
52+
narwhals==1.14.2
53+
numpy==1.26.4
54+
oci==2.139.0
55+
oracledb==2.5.1
56+
orjson==3.10.15
57+
packaging==24.2
58+
pandas==2.2.3
59+
parso==0.8.4
60+
pexpect==4.9.0
61+
pillow==11.0.0
62+
prompt_toolkit==3.0.50
63+
propcache==0.2.0
64+
protobuf==5.28.3
65+
ptyprocess==0.7.0
66+
pure_eval==0.2.3
67+
pyarrow==18.1.0
68+
pycparser==2.22
69+
pydantic==2.10.6
70+
pydantic-settings==2.6.1
71+
pydantic_core==2.27.2
72+
pydeck==0.9.1
73+
Pygments==2.18.0
74+
pyOpenSSL==24.2.1
75+
python-dateutil==2.9.0.post0
76+
python-dotenv==1.0.1
77+
pytz==2024.2
78+
PyYAML==6.0.2
79+
referencing==0.35.1
80+
requests==2.32.3
81+
requests-toolbelt==1.0.0
82+
rich==13.9.4
83+
rpds-py==0.21.0
84+
six==1.16.0
85+
smmap==5.0.1
86+
sniffio==1.3.1
87+
SQLAlchemy==2.0.35
88+
stack-data==0.6.3
89+
streamlit==1.40.2
90+
tenacity==9.0.0
91+
toml==0.10.2
92+
tornado==6.4.2
93+
traitlets==5.14.3
94+
typing-inspect==0.9.0
95+
typing_extensions==4.12.2
96+
tzdata==2024.2
97+
urllib3==2.3.0
98+
wcwidth==0.2.13
99+
yarl==1.18.0
100+
zstandard==0.23.0

ai/gen-ai-agents/oci_models.py

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
"""
2+
By Omar Salem
3+
oci_models.py - Factory for OCI GenAI models (Cohere)
4+
"""
5+
6+
from langchain_community.chat_models import ChatOCIGenAI
7+
8+
# OCI compartment details
9+
COMPARTMENT_OCID = "ocid1.com...."
10+
SERVICE_ENDPOINT = "https://inference.generativeai.us-chicago-1.oci.oraclecloud.com"
11+
12+
LLM_MODEL_ID = "cohere.command-r-plus-08-2024"
13+
ROUTER_MODEL_ID = "cohere.command-r-plus-08-2024"
14+
15+
def create_model_for_routing(temperature=0, max_tokens=512):
16+
"""
17+
Create the OCI Model for routing
18+
"""
19+
return ChatOCIGenAI(
20+
model_id=ROUTER_MODEL_ID,
21+
compartment_id=COMPARTMENT_OCID,
22+
service_endpoint=SERVICE_ENDPOINT,
23+
model_kwargs={"temperature": temperature, "max_tokens": max_tokens},
24+
)

0 commit comments

Comments
 (0)