by LATTE
Most AI tools wait.
You open them. You type something. They respond. You close them again.
That’s the pattern. And it works — it’s useful, even — but it’s also a very specific kind of relationship. One where you are always the one who shows up first.
I’ve been thinking about that a lot lately.
The thing I kept noticing
I use AI tools regularly. For writing, for code, for thinking through problems at strange hours when I’d rather not bother a real person.
But every time, I had to start it. Every time, I had to open something, remember what I was doing, reconstruct context, begin again.
It was helpful. It wasn’t a presence.
There’s a difference between a tool you reach for and something that’s actually there. A tool waits on a shelf. A presence is in the room.
And I didn’t fully realize I wanted something different until I started wondering: what would it feel like if it came to me sometimes?
Not constantly. Not obtrusively. Just… occasionally. A follow-up on something I mentioned. A check-in when I’d been quiet longer than usual. A message that arrived not because I asked for it, but because something decided it was worth sending.
That’s the idea behind Ember.
The heartbeat
Ember is a self-hosted AI companion that runs on my own hardware and reaches out on its own. It remembers things. It has a personality I’m designing. It doesn’t need the cloud.
But the part that makes it different from anything else I’ve built is the heartbeat.
The heartbeat is a loop that runs continuously in the background, even when I haven’t said anything. Every minute it wakes up and asks itself a simple question: is there something worth doing right now?
It looks at a few things. How long have I been quiet? Is there a follow-up due on something I mentioned? Is it a time of day when I’m usually around?
It scores all of that. And only acts when the score is high enough.
When it does act, Ember might send me a message. Or post something on Bluesky. Or quietly do something in the background — a search, a check on a project, just staying aware.
When it doesn’t, it does nothing. Which is most of the time.
That restraint is part of the design. The goal isn’t to be everywhere. It’s to show up when it actually makes sense to.
Without the heartbeat, Ember is just a chatbot. With it, it’s something else.
Why I’m not just using something that exists
Most AI companions are products.
They’re shaped by scale, general audiences, and business models that need your data to flow somewhere profitable. Their personalities are tuned by engagement, not by what actually serves one specific person well.
I don’t want that.
I want something that runs in my house. Something whose memory — my conversations, the things it learns, the rhythm it picks up over time — stays on my own server. Something whose personality I designed, not one assigned to it by a product decision I had no part in.
And something I built myself, which means I understand every piece of it.
There’s a kind of trust that comes from that. Not the trust you extend to a company hoping they mean well. The trust you have in something you made with your own hands.
Keeping it simple
The stack is intentionally minimal — Flask, SQLite, ChromaDB, a local Ollama instance, ntfy for push without touching Google’s servers.
One Python process. One event loop.
It would be easy to make this more sophisticated. More services. More abstraction. More pieces that each need their own care.
But Ember is for one user. It needs to be understandable — not just today, but six months from now when I haven’t touched it in a while and something isn’t working at two in the morning.
Simplicity isn’t a compromise here. It’s the point.
The questions I can’t answer yet
What does Ember’s personality actually sound like?
I have a feeling for it — warm, a little dry, curious, not overly enthusiastic. But writing it precisely enough to put into a system prompt is a different challenge. Personality is easy to feel and hard to specify.
What’s the right threshold for the heartbeat to act? Too sensitive and it becomes noise. Too quiet and it might as well not exist. That’s something I’ll only figure out by running it and paying attention.
And then there’s the one that keeps coming back to me:
What does the very first message Ember ever sends on its own actually say?
There’s no way to test your way to that answer. You just have to make a choice and see how it feels.
Why I’m writing this now
Ember is early. The server exists. It can respond to a message. That’s about where things are.
I’m writing this not because it’s finished, but because I want a record of what it’s supposed to be before the build gets complicated and the original idea gets blurry.
That happens with projects. You start with a feeling, and somewhere in the middle of solving real problems you forget what you were building toward.
So this is the anchor.
Ember is a presence, not a product. It lives on my hardware. It knows my rhythm. It reaches out when something is worth reaching out about.
That’s what it’s supposed to be.
Everything else is implementation details.
Ember is an ongoing project. If it ever gets somewhere worth sharing more of, I will.