PicoClaw

One PicoClaw Telegram animation made 228,419 edit attempts

A PicoClaw report says one failed turn left a Telegram feedback animation editing every three seconds for days: 228,419 attempts, 43,165 successful edits and a 3,369-second rate limit. Related work asks for after-turn message steering and privacy-preserving interactive commands.

← Back to homeOriginal source ↗

sipeed/picoclaw issue #3343 is the inspected primary source: “[BUG] Tool feedback animation can edit a Telegram message indefinitely after a failed turn.” The related records below were inspected as supporting context rather than independent confirmation.

The facts

- sipeed/picoclaw issue #3343 was created 2026-08-22T08:41:37Z and was open at inspection; its title is “[BUG] Tool feedback animation can edit a Telegram message indefinitely after a failed turn.” - sipeed/picoclaw issue #3342 was created 2026-08-21T10:34:15Z and was open at inspection; its title is “[Feature] Opt-in "after-turn" steering mode: queue busy-session messages instead of interrupting the running turn.” - sipeed/picoclaw PR #3341 was created 2026-08-19T13:08:21Z and was closed at inspection; its title is “feat(telegram): add interactive command UX and formatted ephemeral fallback.” - The repository reported 29911 stars, 41 open issues, default branch main, and last push 2026-08-19T09:17:33Z. - The latest tagged-release baseline checked was nightly published 2026-07-02T01:26:53Z.

What changed

sipeed/picoclaw issue #3343 reports: Quick Summary A tool feedback animation continued calling Telegram's editMessageText every three seconds for several days after the associated agent turn stopped making progress. This produced over 228,000 edit attempts and caused Telegram to apply a server-side rate limit with a retry_after of nearly an hour. Restarting the gateway stopped the animation, but Telegram remained unavailable until the penalty expired. I checked v0.3.1 and current main. The relevant animator implementation is unchanged and still has no lifetime limit or error-based termination. Environment & Tools **PicoClaw Version:** nightly-2-g8d712e30 **Build date:** 2026-05-30 **Go Version:** go1.25.10 **AI Model & Provider:** GPT-5.5 through OpenAI OAuth **Operating System:** Ubuntu on Raspberry Pi **Channel:** Telegram Steps to Reproduce 1. Enable tool feedback for Telegram. 2. Start a turn that invokes a tool, causing PicoClaw to create and animate a tool feedback message. 3. Let the turn fail or otherwise exit through a path that does not finalize or dismiss the tracked feedback message. 4. Observe repeated editMessageText requests every three seconds after the turn has ended. The original turn involved an exec tool call. The provider later failed, and the tool feedback message remained tracked. Actual Behavior ToolFeedbackAnimator.run continues until its stop channel is closed: There is no maximum duration, and the result of editFn is ignored. In this incident: The affected feedback message was created

sipeed/picoclaw issue #3342 reports: The Goal / Use Case When a user sends a second message while the agent is still processing the first one, the current steering design treats it as a mid-task course correction: the remaining tool calls of task #1 are skipped ("Skipped due to queued user message.") and message #2 is injected into the running context. In real chat usage (Telegram, Feishu,...), most busy-time messages are **follow-up questions or new independent tasks**, not corrections. The observable result: task #1 is cut off mid-flight and effectively forgotten the model pivots to message #2 (recency bias) and answers are merged only one combined reply comes back This has been reported multiple times, but was triaged as a channel bug and stale-closed without resolution: #2447 ("Only the latest message is processed") #2464 ("连续发送消息后,只响应了最后一条" — consecutive messages, only last answered) #2446 (related multi-channel concurrency acknowledgment: "limitations in the existing design") Proposed Solution An opt-in config value that changes what a busy-session inbound message means: "mid-turn" (default, current behavior) | "after-turn" (new) With "after-turn": 1. Busy-session messages stay in the existing per-session steering queue (no code path change) 2. Mid-turn dequeues are disabled → task #1 always runs to completion, no skipped tools 3. After the turn ends, the existing post-turn drain (drainQueuedSteeringContinuations) processes each queued message as its own complete turn

sipeed/picoclaw PR #3341 reports: Problem Statement 1. The Telegram command experience currently requires full subcommand grammar (CLI-style) for /memory, increasing cognitive load. 2. The default /help command output is overly verbose because it displays full subcommand grammars in each row. 3. When structured content is delivered through ephemeral/private routes in Telegram groups/supergroups, formatting is stripped down to plain text without utilizing supported Telegram MarkdownV2/HTML entities. Architecture & Ephemeral Privacy **Formatted Ephemeral Fallback:** Implements deterministic MarkdownV2/HTML parsing on ephemeral routes using parseContent. If Telegram rejects entities (isTelegramParseRejection), it seamlessly falls back to plain text while maintaining private receiver authority (applyEphemeralSendMessage). **Strict Privacy Invariant:** Ephemeral group responses **never** fall back to public sendRichMessage. **Interactive /memory Dashboard:** Invoking /memory with no arguments opens a structured interactive dashboard with pagination, state-aware actions (pin, unpin, archive, restore, forget, approve, reject), and ForceReply flows for search and edit. **Fail-Closed Privacy:** In public groups without private/ephemeral authority, /memory fails closed without disclosing personal data. **Opaque Callback Security:** Callbacks use minimal opaque tokens (e0, e1) capped within Telegram's 64-byte limit without encoding raw durable memory IDs, session keys, or private contents. **ForceReply Flows:** Prompts for search queries and memory editing are strictly bound to owner, chat, thread, and prompt message ID, and are consumed once to prevent leaking into the LLM conversation pipeline. **Compact /help:** Renders root slash commands and concise descriptions,

Why it matters

Channel polish becomes an outage when animation lifetime, busy-message meaning and private reply authority are implicit. The operator test is whether the system remains bounded and its receipts still describe the action after failure, retry or restart.

Current

The primary record was open when captured on 2026-08-24. The tagged-release baseline was nightly published 2026-07-02T01:26:53Z. Repository metadata, full source bodies, current pull requests and issues, releases, Google News, Hacker News, Lobsters, Metamesh and the rendered ClawCharts row were inspected. ClawCharts selected the subject; it did not prove the claim.

Evidence

The primary URL is https://github.com/sipeed/picoclaw/issues/3343. Supporting records are https://github.com/sipeed/picoclaw/issues/3342 and https://github.com/sipeed/picoclaw/pull/3341. Source bodies, timestamps and states are preserved in the daily evidence bundle. Test counts and reproductions remain attributed to their authors unless identified as independently rerun.

Source boundary

Open work is described as open, closed work as closed, and operator reports as reports. A pull request is evidence of proposed or reviewed direction, not proof of a shipped release. Search residue, package mirrors and historically published source spines were excluded.

Operator take

Stop animations on every turn exit, bound their lifetime, honor retry_after, and keep interruption semantics explicit rather than treating every follow-up as a correction. Preserve a before-state receipt, make the smallest reversible change, and verify the original failure independently.

Caveat

Public project records are mutable. Status, scope and evidence can change after publication. This brief records the inspected state and does not authorize changes to a reader’s deployment.

Source inspected; source state, environment and release boundary remain explicit.