Skip to content

Commit 035b030

Browse files
committed
Fix thread selection issue and improve thread titles
- Add thread_id prefix to titles for uniqueness (fixes Streamlit selectbox issue with duplicate titles) - Handle image-only messages with 📸 Image title - Remove o1-mini (doesn't support tools) - Add gpt-5 model support
1 parent 1ad3691 commit 035b030

File tree

3 files changed

+30
-11
lines changed

3 files changed

+30
-11
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ A reference implementation for building chat applications with LangGraph and Str
1717

1818
## Implemented Providers
1919

20-
- **OpenAI**: GPT-4o, GPT-4 Turbo, o1, o3-mini
20+
- **OpenAI**: GPT-5, GPT-4o, GPT-4o-mini, GPT-4 Turbo, GPT-4, o1, o3-mini
2121
- **Anthropic**: Claude Sonnet 4, Claude 3.7 Sonnet, Claude 3.5 Sonnet/Haiku
2222

2323
Additional providers can be easily added by implementing the `AgentConfig` interface (see [Adding Custom Agents](#adding-custom-agents)).

app/agents/openai_agent.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,12 +26,12 @@ def render_options() -> dict[str, Any]:
2626
options["model"] = st.selectbox(
2727
"Model",
2828
[
29+
"gpt-5",
2930
"gpt-4o",
3031
"gpt-4o-mini",
3132
"gpt-4-turbo",
3233
"gpt-4",
3334
"o1",
34-
"o1-mini",
3535
"o3-mini",
3636
],
3737
index=0,
@@ -40,7 +40,7 @@ def render_options() -> dict[str, Any]:
4040
)
4141

4242
# o1/o3 models don't support temperature parameter
43-
is_thinking_model = options["model"] in ["o1", "o1-mini", "o3-mini"]
43+
is_thinking_model = options["model"] in ["o1", "o3-mini"]
4444

4545
if not is_thinking_model:
4646
options["temperature"] = st.slider(

app/utils.py

Lines changed: 27 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -106,29 +106,48 @@ def get_threads(checkpoint: SqliteSaver) -> tuple[list[str], str | None]:
106106

107107

108108
def get_thread_title(thread_id: str) -> str:
109-
"""Get the title for a thread based on its first message."""
109+
"""Get the title for a thread based on its first message.
110+
111+
Includes thread_id prefix to ensure uniqueness in the UI.
112+
"""
110113
tup = st.session_state.checkpoint.get_tuple({"configurable": {"thread_id": thread_id}})
111114
if not tup:
112-
return "New thread"
115+
return f"[{thread_id[:8]}] New thread"
113116

114117
messages = getattr(tup, "checkpoint", {}).get("channel_values", {}).get("messages", [])
115118
if not messages:
116-
return "New thread"
119+
return f"[{thread_id[:8]}] New thread"
117120

118121
content = getattr(messages[0], "content", None)
122+
title = None
123+
has_image = False
119124

120125
# String content
121126
if isinstance(content, str) and content.strip():
122-
return content.strip().splitlines()[0]
127+
title = content.strip().splitlines()[0]
123128

124129
# List content (multimodal)
125-
if isinstance(content, list):
130+
elif isinstance(content, list):
126131
for part in content:
127-
if isinstance(part, dict) and part.get("type") == "text":
132+
if not isinstance(part, dict):
133+
continue
134+
135+
part_type = part.get("type")
136+
if part_type == "text":
128137
if text := part.get("text", "").strip():
129-
return text.splitlines()[0]
138+
title = text.splitlines()[0]
139+
break
140+
elif part_type == "image_url":
141+
has_image = True
142+
143+
if title:
144+
return f"[{thread_id[:8]}] {title}"
145+
146+
# Image-only message
147+
if has_image:
148+
return f"[{thread_id[:8]}] 📸 Image"
130149

131-
return "New thread"
150+
return f"[{thread_id[:8]}] New thread"
132151

133152

134153
def on_delete_thread(thread_id: str) -> None:

0 commit comments

Comments
 (0)