polygram 0.12.1 → 0.12.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -322,7 +322,7 @@ mcp.setRequestHandler(ListToolsRequestSchema, async () => {
322
322
  // (P0 spike Q-B: claude echoes only the trigger id) — this array can.
323
323
  consumed_turn_ids: {
324
324
  type: 'array', items: { type: 'string' },
325
- description: 'turn_id of EVERY <channel> message this reply answers or has absorbed since your last reply (including mid-turn follow-ups). Always set it.',
325
+ description: 'turn_id of EVERY <channel> message this reply answers or has absorbed since your last reply, including mid-turn follow-ups. Set it on EVERY reply, even short one-line ones; if you answered two messages in one reply, list BOTH turn_ids. Omitting a folded follow-up makes polygram treat it as dropped.',
326
326
  },
327
327
  },
328
328
  required: ['chat_id', 'text'],
@@ -754,11 +754,14 @@ class CliProcess extends Process {
754
754
  'as normal — only the FINAL user-visible message needs to go through',
755
755
  'the reply tool.',
756
756
  '',
757
- 'When you call `reply`, ALWAYS set `consumed_turn_ids` to the turn_id',
758
- 'attribute of EVERY <channel> message you are answering or have received',
759
- 'since your last reply including mid-turn follow-ups you absorbed into',
760
- 'the current answer. polygram uses it to confirm follow-up delivery;',
761
- 'omitting it can cause a follow-up to be re-sent to you.',
757
+ 'When you call `reply`, ALWAYS set `consumed_turn_ids` to the turn_id of',
758
+ 'EVERY <channel> message this reply answers or folds in — every mid-turn',
759
+ 'follow-up you absorbed since your last reply. This applies to EVERY reply,',
760
+ 'including SHORT one-line ones: if two messages arrived and you answered both',
761
+ 'in one reply, list BOTH turn_ids (e.g. consumed_turn_ids: ["<original-id>",',
762
+ '"<follow-up-id>"]). Omitting a folded follow-up makes polygram read it as',
763
+ 'DROPPED — it gets re-sent to you or flagged as a lost message. When unsure,',
764
+ 'include the id.',
762
765
  '',
763
766
  '### Staying responsive on a long task',
764
767
  '',
@@ -2129,6 +2132,22 @@ class CliProcess extends Process {
2129
2132
  backend: this.backend,
2130
2133
  });
2131
2134
  this._logEvent('turn-timeout', { turnTimeoutMs, reason });
2135
+ // 0.12.3 wedge characterization (docs/0.13-turn-wedge-autorecovery-spec.md):
2136
+ // a zero-reply turn hit the ceiling = claude wedged (no hooks AND no
2137
+ // "esc to interrupt" the whole window). Capture the TUI pane tail + busy
2138
+ // flags to learn WHAT state claude is stuck in (a tool, an unrecognized
2139
+ // prompt, the idle ❯, blank). Fire-and-forget: never blocks or changes
2140
+ // the kill path; the tmux session is still alive at this point.
2141
+ this.probeBusyState().then((probe) => {
2142
+ this._logEvent('turn-timeout-pane', {
2143
+ reason,
2144
+ streaming: probe.streaming,
2145
+ background_shell: probe.backgroundShell,
2146
+ shell_count: probe.shellCount,
2147
+ captured: probe.captured,
2148
+ pane_tail: probe.paneTail,
2149
+ });
2150
+ }).catch(() => { /* telemetry best-effort — never throws into the kill path */ });
2132
2151
  this.emit('idle');
2133
2152
  const err = new Error(`turn timeout (${turnTimeoutMs}ms, reason=${reason})`);
2134
2153
  err.code = 'TURN_TIMEOUT';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "polygram",
3
- "version": "0.12.1",
3
+ "version": "0.12.3",
4
4
  "description": "Telegram daemon for Claude Code that preserves the OpenClaw per-chat session model. Migration path for OpenClaw users moving to Claude Code.",
5
5
  "main": "lib/ipc/client.js",
6
6
  "bin": {