PM1 Assistant
A lightweight ChatGPT-style assistant that routes the same conversation between OpenAI and open-source Llama models, with local persistence and usage analytics.
pm1-assistant.vercel.app ↗Overview
PM1 Assistant was built at a point when every AI chat product was hard-wired to a single provider. The idea was to treat the model as a swappable backend: the same conversation, the same interface, but the freedom to send a turn to OpenAI or to an open-source Llama model hosted on Together AI and compare what came back.
Key Features
- Model switching mid-conversation: Separate API routes for OpenAI and Llama sit behind one chat surface, so switching providers doesn’t reset context or change the UI.
- Streaming chat interface: A message stream with an auto-resizing composer that grows with the input, built to feel native rather than form-like.
- Local conversation persistence: Chat history is kept client-side via a
useLocalStoragehook, so sessions survive a refresh with no account or backend storage required. - Usage analytics: Mixpanel instrumentation to see which models people actually reached for, and where conversations dropped off.
Technologies Used
- Next.js + TypeScript: App shell and API routes.
- OpenAI API: GPT model access.
- Together AI: Hosted open-source Llama inference.
- Tailwind CSS: Styling.
- Mixpanel: Product analytics.
Challenges and Learnings
Two providers meant two response shapes, two streaming formats, and two failure modes. Normalising them behind a single message contract — so the front-end never knew or cared which model answered — was the design decision that made the rest of the app simple. That pattern of putting a provider-agnostic boundary between the interface and the model is one I’ve carried into every LLM system I’ve built since, including Core Lens.
Outcome
A small, fast assistant that made a real point: the model is an implementation detail. Keeping that boundary clean means a new provider is a config change, not a rewrite.