{"slug": "my-ai-assistant-stopped-working-the-moment-i-closed-the-chat", "title": "\"My AI Assistant Stopped Working the Moment I Closed the Chat\"", "summary": "A developer building CliGate, a local AI control plane, discovered that AI assistants fail when they cannot operate outside of chat sessions. To solve this, they implemented background assistant runs with delayed wake-ups, separate conversation scopes for recurring tasks, and a bridge to user-facing conversations when input is needed. The key insight is that scheduled assistant runs differ fundamentally from simple reminders.", "body_md": "A lot of AI assistants only feel helpful while the chat window is still open.\n\nYou ask for something, watch it think, maybe answer one follow-up, and then you leave.\n\nThat is the moment the illusion breaks.\n\nIf the assistant cannot wake itself up later, run something in the background, and only come back to you when it actually needs you, it is not much of an assistant. It is just a chat box with good manners.\n\nThat was one of the more practical lessons while building [CliGate](https://github.com/codeking-ai/cligate), my local AI control plane for a resident assistant, scheduled work, channels, Claude Code, Codex, and model routing behind one localhost service.\n\nThe old mental model was too chat-shaped.\n\nA user message arrived. The assistant did some work. The answer came back into the same visible thread.\n\nThat works for interactive tasks, but it falls apart for the boring real ones:\n\nIn other words, the assistant needed a way to work *without* pretending the user was still sitting there.\n\nThe first naive version of scheduled work is just:\n\n``` php\nat 8 PM -> send message\n```\n\nThat is fine for \"drink water\" reminders.\n\nIt is useless for anything that needs actual reasoning or tools.\n\nWhat I wanted instead was:\n\n``` php\nat 8 PM -> wake the assistant with an instruction\n-> let it run in the background\n-> send me the result\n-> if it needs input, route my reply back into that paused run\n```\n\nThat sounds small, but it changes what a scheduled task really is. It stops being a timer and starts being a delayed assistant run.\n\nOne subtle bug showed up fast.\n\nIf every recurring run reused the same hidden conversation forever, the assistant started treating later fires like duplicates.\n\nThat is especially bad for recurring work. A scheduled publishing task should not say \"already done\" just because a previous run earlier that day used the same scope and saw similar history.\n\nSo I ended up separating two modes:\n\nThat means a recurring task can wake the assistant in its own background scope conversation, without polluting the user's visible chat and without inheriting the wrong assumptions from the last run.\n\nIn CliGate, that also made the scheduling model much easier to trust: each fire can be a clean round, while things like a running diary can still opt into shared context.\n\nBackground runs do not always finish cleanly.\n\nSometimes the assistant needs the user.\n\nMaybe a credential is missing. Maybe a choice matters. Maybe a risky action needs confirmation.\n\nIf that happens inside a hidden scheduled-task scope, the run cannot just hang there forever.\n\nSo the assistant needed a bridge back to the user-facing conversation.\n\nThe model that finally felt right was:\n\nThat was the difference between \"background automation\" and \"a silent dead end.\"\n\nOne thing I like about this setup is that the user-facing choice is simple.\n\nA scheduled task can either:\n\nAnd when invoking the assistant, two more controls matter a lot:\n\nThat is enough surface area to be useful without turning scheduling into a mini workflow engine.\n\nMost people do not want cron trivia. They want to say:\n\nThat is the level an assistant should operate at.\n\nThe biggest win was not technical elegance.\n\nIt was behavioral honesty.\n\nThe assistant no longer had to pretend every task was a live chat exchange.\n\nNow it can:\n\nThat made CliGate feel a lot less like \"chat with extra steps\" and a lot more like an actual local operator.\n\nIf you are building AI assistants, this is the line I would not blur: a scheduled reminder is not the same thing as a scheduled assistant run, and users feel the difference immediately.", "url": "https://wpnews.pro/news/my-ai-assistant-stopped-working-the-moment-i-closed-the-chat", "canonical_source": "https://dev.to/codekingai/my-ai-assistant-stopped-working-the-moment-i-closed-the-chat-2j5c", "published_at": "2026-06-30 07:17:56+00:00", "updated_at": "2026-06-30 07:49:08.101168+00:00", "lang": "en", "topics": ["artificial-intelligence", "ai-agents", "developer-tools", "ai-products", "ai-infrastructure"], "entities": ["CliGate", "Claude Code", "Codex"], "alternates": {"html": "https://wpnews.pro/news/my-ai-assistant-stopped-working-the-moment-i-closed-the-chat", "markdown": "https://wpnews.pro/news/my-ai-assistant-stopped-working-the-moment-i-closed-the-chat.md", "text": "https://wpnews.pro/news/my-ai-assistant-stopped-working-the-moment-i-closed-the-chat.txt", "jsonld": "https://wpnews.pro/news/my-ai-assistant-stopped-working-the-moment-i-closed-the-chat.jsonld"}}