📁 File Structure
projects/trendmate/
├── app.py— CLI terminal version of the research assistant
├── web_app.py— Streamlit web interface (main app)
├── system-prompt.txt— Agent persona, Malaysian fashion focus, 3-sentence format rules
├── requirements.txt— Python dependencies
├── .env.example— API key template
├── demo.html— Static interactive demo page
├── user-guide.md— Plain language setup and usage guide
├── problem-statement.md— Problem definition and target users
└── project-outline.md— App name, features, tech stack, roadmap
🔑 Key Code: Agent Loop (web_app.py)
TrendMate uses the same ReAct loop as MyPropLex — Claude decides what to search, calls Tavily, reads results, and iterates. The difference is the system prompt which steers Claude toward Malaysian fashion market sources and forces actionable, market-specific answers.
def run_agent(user_message, history, client, tavily, system_prompt):
history.append({"role": "user", "content": user_message})
while True:
response = client.messages.create(
model="claude-sonnet-4-6",
max_tokens=2048,
system=system_prompt,
tools=TOOLS,
messages=history
)
if response.stop_reason == "end_turn":
text = "\n".join(b.text for b in response.content if hasattr(b, "text"))
history.append({"role": "assistant", "content": response.content})
return text
elif response.stop_reason == "tool_use":
history.append({"role": "assistant", "content": response.content})
tool_results = []
for block in response.content:
if block.type == "tool_use" and block.name == "search_web":
tool_results.append({
"type": "tool_result",
"tool_use_id": block.id,
"content": search_web(block.input["query"], tavily)
})
history.append({"role": "user", "content": tool_results})
🔑 Key Code: System Prompt (system-prompt.txt)
The system prompt is what makes TrendMate a fashion specialist instead of a general chatbot. It tells Claude exactly which sources to prioritise, what format to use, and how to make every answer actionable for a Malaysian seller.
1. Search for the latest information before answering.
Fashion moves fast — always find current data.
2. Give actionable, specific recommendations. Not just
"baju kurung is trending" but "baju kurung moden in
pastel colours is trending for Raya 2025, priced
between RM89–RM149 on Shopee."
3. When talking about prices, always mention the
Malaysian market specifically.
- Maximum 3 sentences per answer. No exceptions.
- Sentence 1: Direct finding or recommendation (specific:
product type, platform, price range).
- Sentence 2: One piece of evidence (trending on TikTok,
top-selling on Shopee, sourcing tip).
- Sentence 3: One action the seller should take right now,
or a timing note.
🔑 Key Code: Preset Questions in Sidebar
Preset questions are displayed as clickable sidebar buttons. When clicked, the question is set in session state and processed on the next render cycle — the same flow as typing a question manually.
for i, q in enumerate(PRESET_QUESTIONS):
if st.button(f"{i+1}. {q}", key=f"q{i}", use_container_width=True):
st.session_state.pending_q = q
prompt = None
if st.session_state.pending_q:
prompt = st.session_state.pending_q
st.session_state.pending_q = None
elif q := st.chat_input("Type your fashion market question..."):
prompt = q
if prompt:
answer = run_agent(prompt, st.session_state.conv_history, ...)
📦 Dependencies (requirements.txt)
anthropic>=0.40.0
tavily-python>=0.3.0
python-dotenv>=1.0.0
streamlit>=1.32.0