{"slug": "build-ai-agents-with-hot-dev", "title": "Build AI Agents with Hot Dev", "summary": "Here is a factual summary of the article:\n\nThe article explains how to build AI chat agents with two distinct memory scopes using Hot Dev: a Personal Mode that remembers user-specific information across devices, and a Team Mode that shares memory among all users within a specific channel. The provided demo, Hot Chat, is a Next.js and TypeScript application that runs two agents side-by-side, with the agent layer built on the open-source `hot-ai-agent` package, which handles transports, commands, and streaming. The walkthrough details how to clone and run the demo locally, configure API keys for Anthropic, and switch between the two memory modes live without restarting the server.", "body_md": "Learn how to build AI chat agents with two kinds of memory: one that follows a user across devices, and one shared by everyone in a channel.\n\n**Hot Chat** is a web chat demo you can clone and start in about 15 minutes, with two AI agents side by side: a **Personal Mode** agent whose memory is keyed to the user, and a **Team Mode** agent whose memory is keyed to the channel.\n\nThe UI is a Next.js + TypeScript app that talks to Hot through [ @hot-dev/sdk](https://www.npmjs.com/package/@hot-dev/sdk). The agent layer is built on\n\n[, a reusable Hot package for transports, commands, runtime stores, rendering, streaming, and MCP helpers. Hot Dev itself is](https://hot.dev/pkg/hot.dev/hot-ai-agent)\n\n`hot.dev/hot-ai-agent`\n\n[open source under Apache 2.0](https://github.com/hot-dev/hot), so everything you see in this post runs on code you can read.\n\n## Try It\n\nBefore running the demo, [install Hot](https://hot.dev/docs/getting-started) if you don't already have the `hot`\n\nCLI.\n\n```\ngit clone https://github.com/hot-dev/hot-demos\ncd hot-demos/hot-chat\nhot dev --open                  # terminal 1: both agents\ncp .env.example .env            # terminal 2: the UI\n# Hot App -> API Keys -> New Key; paste it into HOT_API_KEY.\n# Then add your ANTHROPIC_API_KEY (https://console.anthropic.com/) to .env.\nnpm install && npm run dev\n```\n\nOpen [http://localhost:3000](http://localhost:3000). The toolbar switches between the two agents live, no restart needed.\n\nSet `ANTHROPIC_API_KEY`\n\nin `.env`\n\nto get the real, streamed, memory-grounded replies the demo is built around. Without it the UI still loads, but assistant replies fall back to a stub that just says the LLM is disabled. The harness sits on [ hot-ai](https://hot.dev/pkg/hot.dev/hot-ai), so you can wire a different provider in your own app.\n\nThe full walkthrough is at [hot.dev/docs/demos/hot-chat](https://hot.dev/docs/demos/hot-chat).\n\n## Two Agents, One Project\n\nHot Chat ships two agents in one Hot project. They look nearly identical on the surface: same chat UI, same slash commands, same streaming replies.\n\nThe difference is how each one scopes memory.\n\n**Personal Mode** is identity-first. Whatever you tell the agent follows *you* across sessions, tabs, and devices. Type `/remember I prefer launch updates that start with blockers`\n\n, close the tab, come back tomorrow on a different device, ask `/recall`\n\n, and the same notes are still there.\n\nThis is the pattern for assistants, journaling apps, per-user copilots, and anything where memory belongs to the person rather than the conversation.\n\n**Team Mode** is session-first. Memory is keyed to the channel, so two people chatting in the same room share one view, and two channels stay independent. Type *\"we decided to ship docs before launch\"*, then *\"CI is the only blocker\"*, then `/ask what is blocking launch?`\n\n, and the reply cites the matching records with attribution.\n\nThis is the pattern for team chat bots, support inboxes, and shared workspaces.\n\n| Concept | Team Mode | Personal Mode |\n|---|---|---|\n| Session | the channel or thread | a scratch context per person |\n| Identity | the person who posted | the durable memory owner |\n| Memory | scoped to the session | scoped to the user |\n\n*Hot Chat, mid-conversation. The toolbar switches between Personal and Team mode live.*\n\n## Inside the UI\n\nThe Hot Chat UI is intentionally generic. It looks like a chat product, not a framework demo. That's because the experience is the point:\n\n-\n**Quick-prompt chips** help you explore each mode without learning a syntax first. Try*Recall preferences*,*Daily brief*,*Decisions*, or*Ask the team*. -\n**Streaming replies** render as the agent generates them. Slash-command replies stream too, identically to LLM responses, so the UI doesn't have to know which path produced the message. -\n**File attachments** let you drag in a small`notes.md`\n\nfile or screenshot. The agent stores the file name and type as metadata and could be extended to parse contents. -\n**Identity controls** show the exact`session_id`\n\nand`user_id`\n\nthe agent receives, in the same format a Slack or Telegram adapter would generate. -\n**Agent Graph** in the Hot Dev App shows each slash command as its own typed event handler, so you can see the agent structure without digging through a central dispatch function.\n\n*One event handler per command, no central dispatch.*\n\n## What `hot-ai-agent`\n\nBrings\n\nIf you've built an AI chat agent before, you've probably written some version of this stack:\n\n- a slash-command parser\n- a way to thread LLM calls through retrieval-augmented memory\n- a streaming reply mechanism\n- per-agent stores for state and stats\n- per-request session and identity bindings so tools know who's talking\n\nMost chat agents end up reinventing these pieces.\n\n`hot-ai-agent`\n\nextracts that layer. Concretely, it gives you:\n\n-\n**Typed transport messages**: a single`IncomingMessage`\n\nshape that adapters for web, Slack, Telegram, or anything else can translate into. The agent never branches on transport. -\n**Slash-command parsing**:`/ask@MyBot what's up?`\n\nbecomes`{name: \"ask\", arg: \"what's up?\"}`\n\n, with the Telegram-style`@MyBot`\n\nsuffix stripped. -\n**The memory-grounded chat turn**: the canonical`recall -> persist user -> bind request -> stream -> persist assistant`\n\nlifecycle in one function call. The order matters; getting it wrong can cause the user's fresh message to contaminate their own retrieval. -\n**Stable streaming events**: every agent emits`<agent>:reply:start`\n\n,`:delta`\n\n, and`:end`\n\nevents at a stable, agent-scoped label. -\n**Per-request session binding**: when an LLM tool runs mid-turn, the resolved session and identity are bound to the current agent request. -\n**Per-agent stores and a session registry**: each agent gets state, stats, errors, and a notification ledger. Scheduled jobs can fan out per session with error isolation. -\n**MCP plumbing**: expose any agent function as an MCP tool with one annotation, so Claude Desktop, Cursor, and other MCP clients can call into the agent directly.\n\nWhat it deliberately doesn't include: transport vendor packages. No Slack, Telegram, or Discord packages are baked in. Those live in the application and translate to the neutral types, which keeps the harness portable and the dependency tree small.\n\n## Under the Hood, in One Snippet\n\nWhen all the harness pieces are in place, an entire chat-style event handler in Hot looks like this:\n\n```\nremember-message\nmeta {\n    agent: PersonalAgent,\n    on-event: \"personal-agent:remember\",\n}\nfn (event) {\n    d        event.data\n    sender   identity-from-data(d)\n    session  session-from-data(d, sender)\n    input    base-input(d, session, sender, Str(or(d.text, \"\")))\n    ::chat-turn/run-chat-turn(turn-cfg, input)\n}\n```\n\nThat's the whole handler. Resolve who's talking, package up the input, and hand off to `run-chat-turn`\n\n.\n\nRAG, persistence, ordering, streaming, request binding, tool dispatch, and error handling sit behind that one call.\n\nAdding a new slash command in your own agent follows the same pattern: one more function, one more `on-event`\n\nannotation.\n\n## Where to Go Next\n\nClone Hot Chat and try swapping the LLM provider, adding a slash command, or wiring a second adapter on top of the same agent. Everything below is open source and free to read.\n\n-\n**Run Hot Chat:**[hot.dev/docs/demos/hot-chat](https://hot.dev/docs/demos/hot-chat) -\n**Hot Chat source:**[github.com/hot-dev/hot-demos/tree/main/hot-chat](https://github.com/hot-dev/hot-demos/tree/main/hot-chat) -\n`hot-ai-agent`\n\npackage:[hot.dev/pkg/hot.dev/hot-ai-agent](https://hot.dev/pkg/hot.dev/hot-ai-agent) -\n`hot-ai`\n\npackage:[hot.dev/pkg/hot.dev/hot-ai](https://hot.dev/pkg/hot.dev/hot-ai) -\n`@hot-dev/sdk`\n\nfor JS/TS:[npmjs.com/package/@hot-dev/sdk](https://www.npmjs.com/package/@hot-dev/sdk) -\n**Hot Dev on GitHub (Apache 2.0):**[github.com/hot-dev/hot](https://github.com/hot-dev/hot) -\n**Follow Hot Dev:**[@hotdotdev on X](https://x.com/hotdotdev)", "url": "https://wpnews.pro/news/build-ai-agents-with-hot-dev", "canonical_source": "https://dev.to/curtissummers/build-ai-agents-with-hot-dev-3po6", "published_at": "2026-05-23 11:47:54+00:00", "updated_at": "2026-05-23 12:02:33.201776+00:00", "lang": "en", "topics": ["artificial-intelligence", "large-language-models", "open-source", "developer-tools"], "entities": ["Hot Dev", "Hot Chat", "Next.js", "TypeScript", "Anthropic", "Apache 2.0"], "alternates": {"html": "https://wpnews.pro/news/build-ai-agents-with-hot-dev", "markdown": "https://wpnews.pro/news/build-ai-agents-with-hot-dev.md", "text": "https://wpnews.pro/news/build-ai-agents-with-hot-dev.txt", "jsonld": "https://wpnews.pro/news/build-ai-agents-with-hot-dev.jsonld"}}