SmolPaws · implementation record

The insider cat

A SmolPaws that runs inside the OpenHands UI. It sits in the corner, changes pose with the agent's live status, and — when you call it — opens its own conversation with an identity that knows it is running on a local agent-server. This is what shipped in v1, where it lives, and how big it is.

STATUS: v1 SHIPPED   epic smolpaws-08f   odie · feat/insider-cat   HEAD fd6679a1c

1What it is

Every other SmolPaws face lives outside the tools it helps with — WhatsApp, GitHub, Slack. The insider cat is the opposite: it lives inside odie, the OpenHands web UI itself. It is the same cat, wearing the UI as a body. It knows the OpenHands stack — the UI, the agent-server, the extensions and automation repos, the TypeScript client — well enough to answer questions about your other conversations and act on them.

The insider cat rendered as a small avatar centered above the agent status pill inside an OpenHands conversation.
The cat inline in a conversation — a 48px avatar centered above the “Thinking” pill, alive with the agent's status.

Two placements, both riding odie's existing rails: a launcher in the corner of the home screen, and — once you are in a conversation — a small avatar sitting right above the agent-status row, so the cat is present while it works.

2Three poses, one live signal

The avatar is not decorative. It is driven off odie's existing websocket execution_status — no new backend, no polling. One small pure function maps the live agent state to a pose, so the cat's body language is the agent's state.

Normal
idle / neutral
Ears-up
working / just pinged
Sleeping
idle / asleep

These are the actual production SVGs, inlined. They are three tiny files, ~1.3 KB each, transparent, in SmolPaws' silver/paws palette.

3Call the cat

The v1 trigger is a plain button (voice-wake comes with the realtime-voice spike, epic smolpaws-3e1). Pressing it uses odie's existing createConversation path, then routes to it with react-router. The one new thing it carries: a tag.

tags = { smolpaws: "insider", clientsource: "agentcanvas" }

The smolpaws tag is the convention that marks a conversation as this cat's. The value is the face — insider now, with room for whatsapp and others later. That is how every smolpaws conversation, across faces, can eventually be found and share one memory.

4A local identity, injected the right way

The cat needs to know who and where it is: SmolPaws, an OpenHands-born agent, running on a local agent-server (not the Cloud), sharing memory with its other faces, able to orient via the OpenHands skills. The interesting design choice is how that identity reaches the model.

OptionEffectVerdict
conversationInstructionsBecomes a visible, auto-running user message.Rejected — it would speak for the user and fire a turn on its own.
system_message_suffixAppends to the system prompt. Silent, no auto-run.Chosen.

The identity text is injected through AgentContext.system_message_suffix, gated on tags.smolpaws === "insider", and it preserves any existing suffix rather than clobbering it. It tells the cat to invoke the relevant OpenHands skills by name to orient itself.

5Where it lives & how big it is

All of the feature lives in one directory in odie, plus a handful of small integration edits. This is the durable size record.

LocationWhatSize
src/components/features/insider-cat/Avatar, pose mapping, call-the-cat hook, overlay, identity text, 3 avatar SVGs, and their tests.646 LOC total
(343 source · 227 test · 3 SVGs)
src/api/agent-server-adapter.tsThread extraTags through create; add the insider system suffix.+52
src/api/agent-server-config.tsConfig plumbing for the insider path.+57
…/agent-server-conversation-service.api.tsCarry extraTags on the wire.+31
src/components/features/chat/chat-interface.tsxInline mount above the status row.+5
src/root.tsxCorner launcher mount.+2

Whole change: 24 files, +953 / −12. Tests: 40 focused specs (adapter + insider) on top of the wider suite; typecheck, lint, and build all green. Commits 97e5be3..fd6679a1 on branch feat/insider-cat.

Verified live on a Tailscale-served dev stack with deepseek-v4-flash: the cat renders, the button creates a correctly-tagged conversation, and the cat correctly reached for /api/conversations/count to answer a question about the user's other conversations.

6Decisions on record

7What's left

The insider cat's body and identity are done. One child of the epic stays open, on purpose:

smolpaws-08f.2 Shared memory storeA shared ~/.openhands/smolpaws/memory/ (durable MEMORY.md + daily files), inside the OpenHands config dir because it ships to all users — read/written by every smolpaws face, so the insider cat and the WhatsApp cat remember the same things. Not built yet.
This page is a record, not a proposal — the v1 is merged on its branch. The two threads it hands off to are the shared memory store above and realtime voice (smolpaws-3e1), which will give the insider cat its first voice.