You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
feat: replace task queue with interrupt-first request model
Replace the task-based queue (TaskRunner, TaskStore, UsageStore) with an
interrupt-first RequestRunner. New messages now abort the active request
and start immediately instead of queuing. Simplify sessions to use an
active_sessions pointer table, remove userId from events, and add
first-user lock in the Telegram adapter.
Fix Codex provider retrying after abort by checking the signal before
entering the resume-failure retry path. Fix non-cancellable 3s crash
retry sleep in Claude Code provider. Remove duplicate line in CLAUDE.md.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Copy file name to clipboardExpand all lines: CLAUDE.md
+12-13Lines changed: 12 additions & 13 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -16,18 +16,17 @@ bun run format # Biome format
16
16
17
17
## Architecture
18
18
19
-
Homie is an async Telegram agent that wraps the local `claude` CLI. Users send messages via Telegram, Homie routes them through a gateway to Claude Code, and returns results. Every message becomes a task — there is no casual chat mode.
19
+
Homie is an interrupt-first Telegram agent that wraps local coding CLIs like Codex and Claude Code. Users send messages via Telegram, Homie routes them through a gateway to the local provider, and returns results. The latest message always wins for a chat.
-**No classes.** All modules use factory functions returning interfaces (e.g., `createSessionManager(store): SessionManager`).
48
+
-**No classes.** All modules use factory functions returning interfaces.
51
49
-**No build step.** Bun resolves `.ts` workspace imports directly via `tsconfig.json` path aliases (`@homie/core` → `./packages/core/src`).
52
50
-**SQLite via `bun:sqlite`** with WAL mode. Inline migrations run on `openDatabase()`. Stores are synchronous under the hood but expose async interfaces.
53
-
-**Task queue.** One task runs at a time per chat. New messages queue up (max 10). Sessions are hidden — one per chat, used internally for Claude CLI `--session-id` continuity.
54
-
-**Provider resilience:** Session resume via `--resume`, fallback to full history replay, 1 crash retry with 3s backoff.
51
+
-**Interrupt-first requests.** One request runs at a time per chat. A new message aborts the old request and starts immediately.
52
+
-**Sessions.** Chats can have multiple stored sessions, but only one active session at a time. `/clear` creates a new active session without deleting old history.
53
+
-**Telegram ownership.** The first Telegram user to message the bot becomes the only allowed user until restart.
55
54
-**Preflight checks:** Server startup validates Telegram bot token (`getMe` API) and Claude Code auth (minimal prompt) in parallel before booting.
Copy file name to clipboardExpand all lines: README.md
+17-18Lines changed: 17 additions & 18 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -13,7 +13,6 @@ No API keys. No cloud billing. Just your existing CLI subscriptions.
13
13
-**Remote control** — Telegram is your interface, your machine does the work
14
14
-**Local agents** — wraps CLI agents you already have (Claude Code today, more coming)
15
15
-**Zero API cost** — rides your existing subscriptions, no billing keys needed
16
-
-**Async by design** — fire and forget, check results when you're ready
17
16
-**Self-hosted** — your machine, your data, your agents
18
17
19
18
## Install
@@ -38,16 +37,16 @@ homie
38
37
39
38
Requires [Bun](https://bun.sh) and a supported local agent CLI installed and authenticated. Homie verifies your Telegram token and the configured provider on startup before accepting messages.
40
39
41
-
## Every message is a task
40
+
## Every message is a priority request
42
41
43
-
Every message you send becomes a task. Homie runs it and replies with the result.
42
+
Every message you send starts a request. Homie runs it and replies with the result. Send a photo or file and Homie downloads it to a temp path so the agent can read it natively.
44
43
45
-
If Homie is already working on something, your message gets queued and runs next — up to 10 deep. Send a photo or file and Homie downloads it to a temp path so the agent can read it natively.
44
+
The first Telegram user to message the bot becomes the only allowed user until Homie restarts.
46
45
47
46
```
48
-
/list Recent tasks and their status
49
-
/statusRunning task, queue, and uptime
50
-
/abortCancel the running task and clear the queue
47
+
/statusCurrent request
48
+
/abort Interrupt the active request
49
+
/clearStart a new session
51
50
/help Show commands
52
51
```
53
52
@@ -56,20 +55,22 @@ If Homie is already working on something, your message gets queued and runs next
56
55
```
57
56
Telegram message
58
57
→ Adapter (parse text, photos, documents)
59
-
→ Gateway (resolve session, route command or submit task)
60
-
→ Task runner (queue, execute one at a time per chat)
58
+
→ Gateway (resolve active session, route command or submit request)
**Provider.** Homie wraps local agent CLIs behind a shared runtime contract. Claude Code uses `--output-format stream-json`; Codex uses `exec --json`. Homie parses streamed events, token usage, and final output, then forwards progress and replies back to Telegram.
65
+
**Provider.** Homie wraps local agent CLIs behind a shared runtime contract. Claude Code uses `--output-format stream-json`; Codex uses `exec --json`. Homie parses streamed events and final output, then forwards progress and replies back to Telegram.
67
66
68
-
**Session continuity.** Each chat gets one hidden session. On the first task, Homie sends the full conversation history. On subsequent tasks, it attempts the provider's native resume flow. If resume fails, it falls back to replaying full history in a fresh run. Claude retries once after a crash; Codex currently fails fast.
67
+
**Session continuity.** Each chat has one active session. On the first request in a session, Homie sends the full conversation history. On subsequent requests, it attempts the provider's native resume flow. If resume fails, it falls back to replaying full history in a fresh request. Claude retries once after a crash; Codex currently fails fast.
69
68
70
-
**Queue.** One task runs at a time per chat. The rest sit in an in-memory queue (also tracked in SQLite so status survives restarts). When a task finishes, the next one starts automatically. Aborting kills the running task and clears the entire queue.
69
+
**Interrupt-first flow.** One request is active per chat. A new message interrupts the active request and starts a fresh request immediately. Interrupted partial output is not added to conversation history.
71
70
72
-
**Progress.** While a task runs, Homie sends typing indicators every 4 seconds and a status message every 30 seconds showing elapsed time and what the agent is doing ("Reading files...", "Editing code...", "Running commands...").
71
+
**Fresh context.**`/clear` starts a brand new session for the chat without deleting old history. The next message runs from empty context.
72
+
73
+
**Progress.** While a request is active, Homie sends typing indicators every 4 seconds and a status message every 30 seconds showing elapsed time and what the agent is doing ("Reading files...", "Editing code...", "Running commands...").
73
74
74
75
## Configure
75
76
@@ -78,7 +79,6 @@ Telegram message
78
79
| Setting | Default | What it does |
79
80
|---------|---------|-------------|
80
81
|`telegram.botToken`| — |`TELEGRAM_BOT_TOKEN` env var (required) |
81
-
|`telegram.allowedChatIds`|`[]`| Restrict to specific chats (empty = allow all) |
82
82
|`provider.kind`|`claude-code`| Which CLI backend to use: `claude-code` or `codex`|
83
83
|`provider.model`|`""`| Override the provider's default model; leave empty to follow the CLI default |
84
84
|`provider.extraArgs`|`[]`| Extra CLI flags passed to the agent |
0 commit comments