While I was writing this post I wondered what it would look like if I tried to fit as many song-based quotes as possible in it. With the recent Grammy Awards in mind (and wanting to keep a high calibre of song quotes), I wanted to try building something with this kaggle dataset and the agent APIs to allow adding some custom UI flair
.
While we eventually decided to go with a less-musically themed post, I wanted to publish the example to show just how easy it is to pull an AIP agent into a custom application!
Here’s an example agent I built to help generate these song quotes, with the code for a quick streamlit app, powered using agents with the platform SDK, to show these off in a custom UI:
-
demo video
-
example python code
# app.py
# import the palantir platform SDK
import foundry
import foundry.v2
# import libraries for our custom app and loading configuration for the SDK client
import streamlit as st
from dotenv import dotenv_values
from streamlit_extras.let_it_rain import rain
"""Example .env configuration required:
HOSTNAME=<your hostname, e.g. example.com>
TOKEN=<copy using instructions from https://www.palantir.com/docs/foundry/api/v2/general/overview/authentication/#creating-an-api-bearer-token>
"""
CONFIGURATION = dotenv_values(".env")
@st.cache_resource
def get_client():
auth = foundry.UserTokenAuth(token=CONFIGURATION["TOKEN"])
return foundry.v2.FoundryClient(auth=auth, hostname=CONFIGURATION["HOSTNAME"])
def reset_session():
st.session_state["messages"] = []
st.session_state["session_rid"] = None
with st.sidebar:
agent_rid = st.text_input("AIP Agent RID", key="aip_agent_rid")
"[Create a new AIP Agent](https://www.palantir.com/docs/foundry/agent-studio/getting-started/#create-an-aip-agent)"
st.title("🎵 Shoe-horned song quote generator")
st.button("🔄", on_click=reset_session)
if "messages" not in st.session_state:
st.session_state["messages"] = []
for msg in st.session_state.messages:
st.chat_message(msg["role"]).write(msg["content"])
if prompt := st.chat_input():
if not agent_rid:
st.info("Please add your AIP AGENT RID to continue.")
st.stop()
foundry_client = get_client()
if "session_rid" not in st.session_state or not st.session_state["session_rid"]:
session = foundry_client.aip_agents.Agent.Session.create(agent_rid, preview=True)
session_rid = session.rid
st.session_state["session_rid"] = session_rid
else:
session_rid = st.session_state["session_rid"]
st.session_state.messages.append({"role": "user", "content": prompt})
st.chat_message("user").write(prompt)
with foundry_client.aip_agents.Agent.Session.with_streaming_response.streaming_continue(
agent_rid,
session_rid,
parameter_inputs={},
user_input={"text": prompt},
preview=True
) as response:
# Stream the response from the agent to display in the UI as it's generated
def get_chunk():
for chunk in response.iter_bytes():
yield chunk.decode("utf-8")
st.chat_message("assistant").write_stream(get_chunk)
# Once the response is fully generated, load the full details of the exchange
# including our updated application variables to use for updating our custom application state
updated_session = foundry_client.aip_agents.Agent.Session.Content.get(
agent_rid,
session_rid,
preview=True
)
last_exchange = updated_session.exchanges[-1]
# Display our updated application state
emoji = last_exchange.result.parameter_updates.get("outputEmoji")
if emoji:
rain(font_size=24, emoji=emoji.value, animation_length="10s", falling_speed=2)
st.session_state.messages.append({"role": "assistant", "content": last_exchange.result.agent_markdown_response})
- Relevant libraries