feat(schedule): record delivered Telegram results into the chat session#35
Merged
Conversation
Scheduled tasks ran fully headless and their delivered message was never
written back to the chat's conversation, so a follow-up turn had amnesia
about what the schedule just posted ("what did that scheduled task find?"
hit an agent that never saw its own output).
After a successful Telegram delivery, append the scheduled task + its result
to the target chat's session as a labeled user turn + the assistant result.
The scheduled run itself stays isolated (deterministic) — only its output is
recorded.
Design choices:
- Write-back is serialized through the existing per-chat mutex
(getChatMutex), so it can't interleave with a live interactive turn's
read-modify-write or with a concurrent delivery to the same chat.
- It attaches only to an EXISTING session — a notification-only chat that's
never been used interactively is not given an ever-growing transcript.
- Best-effort: a write-back failure is logged, never fails the run (the
message was already sent) and never triggers redelivery.
- Wired only on the Telegram bot's embedded scheduler (which owns the
SessionManager); the CLI daemon path passes nil and is a safe no-op.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Deploying with
|
| Status | Name | Latest Commit | Preview URL | Updated (UTC) |
|---|---|---|---|---|
| ✅ Deployment successful! View logs |
odek | bc6589c | Commit Preview URL Branch Preview URL |
Jun 12 2026, 04:49 AM |
…g session vprotocol axis 2.1: a chat session can already end on a bare user message — a turn cancelled before the agent replied (telegram.go save-on-cancel) or a context-injection command. The write-back appended its own user turn there, producing two consecutive user messages, which Anthropic rejects with a 400 on the next interactive turn. When the session ends on a user message, fold the scheduled label into a single assistant message instead; either way the session ends on an assistant turn with no two same-role messages in a row. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Scheduled tasks ran fully headless and their delivered Telegram message was never written back to the chat's conversation, so a follow-up turn had amnesia about what the schedule just posted — "what did that scheduled task find?" hit an agent that never saw its own output.
This adds Option B: after a successful Telegram delivery, append the scheduled task + its result into the target chat's session as a labeled user turn (
⏰ [scheduled task "…" ran]) + the assistant result. The scheduled run itself stays isolated and deterministic — only its output is recorded (Option A — feeding the live chat backlog into the run — was deliberately rejected as non-deterministic and a concurrency footgun).Design decisions
getChatMutex), so it can't interleave with a live interactive turn's read-modify-write of the same session, or with a concurrent scheduled delivery to the same chat.SessionManager). The CLIschedule daemon, stdout, and log paths passniland are a safe no-op.Tests (all under
-race)SessionManager(daemon path) is a safe no-op.Full suite green under
go test ./... -race; cleango vet.🤖 Generated with Claude Code