polygram 0.8.0-rc.55 → 0.8.0-rc.56

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.
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "$schema": "https://anthropic.com/claude-code/plugin.schema.json",
3
3
  "name": "polygram",
4
- "version": "0.8.0-rc.55",
4
+ "version": "0.8.0-rc.56",
5
5
  "description": "Telegram integration for Claude Code that preserves the OpenClaw per-chat session model. Migration target for OpenClaw users. Multi-bot, multi-chat, per-topic isolation; SQLite transcripts; inline-keyboard approvals. Bundles /polygram:status|logs|pair-code|approvals admin commands and a history skill.",
6
6
  "keywords": [
7
7
  "telegram",
@@ -1,5 +1,5 @@
1
1
  /**
2
- * Pure formatters for /context command output and the 85%-full hint.
2
+ * Pure formatters for /context command output and the context-full hint.
3
3
  *
4
4
  * Lifted from polygram.js so the formatting can be unit-tested without
5
5
  * spinning up the full handleMessage stack. Both functions are pure —
@@ -12,11 +12,22 @@
12
12
  * 0-1 ratio and multiplied by 100, which displayed "7700% full" and
13
13
  * skipped the 85% hint threshold. The formatters below assume the
14
14
  * 0-100 scale; do not multiply or divide.
15
+ *
16
+ * rc.56 threshold change: default lowered from 85 → 70.
17
+ * Background: at 85% the SDK has typically already auto-compacted
18
+ * mid-turn, so polygram's post-turn check sees a low percentage
19
+ * and the hint never fires. Production data showed 0 user-visible
20
+ * hint triggers across 15 auto-compactions in May 2026, all of
21
+ * which fired at pre_tokens 167-262k (≈85% of Sonnet's 200k
22
+ * window). Lowering to 70% means polygram warns ~30k tokens
23
+ * before the SDK auto-compacts, giving the user 1-3 turns of
24
+ * headroom to choose /new vs /compact vs continue. Configurable
25
+ * per-bot or per-chat via `contextHintThreshold` (number, 0-100).
15
26
  */
16
27
 
17
28
  'use strict';
18
29
 
19
- const HINT_THRESHOLD_PCT = 85;
30
+ const HINT_THRESHOLD_PCT = 70;
20
31
 
21
32
  /**
22
33
  * Format a getContextUsage() result into a multi-line chat reply.
@@ -55,14 +66,20 @@ function formatContextReply(usage) {
55
66
  }
56
67
 
57
68
  /**
58
- * Decide whether to send the 85% hint and return the hint text if so.
69
+ * Decide whether to send the context-full hint and return the hint
70
+ * text if so.
59
71
  *
60
72
  * @param {object} usage — same shape as formatContextReply input.
61
- * @returns {string|null} the hint text to send, or null when below threshold.
73
+ * @param {object} [opts]
74
+ * @param {number} [opts.threshold] — override the default percent
75
+ * threshold (rc.56). Caller resolves per-chat / per-bot config
76
+ * and passes it in. Defaults to HINT_THRESHOLD_PCT (70).
77
+ * @returns {string|null} the hint text to send, or null when below
78
+ * threshold.
62
79
  */
63
- function maybeContextFullHint(usage) {
80
+ function maybeContextFullHint(usage, { threshold = HINT_THRESHOLD_PCT } = {}) {
64
81
  const pct = usage?.percentage ?? 0;
65
- if (pct < HINT_THRESHOLD_PCT) return null;
82
+ if (pct < threshold) return null;
66
83
  return [
67
84
  `📚 Context window ${pct.toFixed(0)}% full. Three options:`,
68
85
  '',
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "polygram",
3
- "version": "0.8.0-rc.55",
3
+ "version": "0.8.0-rc.56",
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": {
package/polygram.js CHANGED
@@ -2859,14 +2859,22 @@ async function handleMessage(sessionKey, chatId, msg, bot) {
2859
2859
  // result, the followup messages (if any) get their own SDK
2860
2860
  // pause to absorb at, no special handling needed.
2861
2861
 
2862
- // 0.8.0 Phase 2 step 4: 85%-context-full live hint. After a
2862
+ // 0.8.0 Phase 2 step 4: context-full live hint. After a
2863
2863
  // successful turn, peek at SDK's getContextUsage(); if past
2864
- // 85%, post a quiet hint so the user knows /new will help.
2865
- // SDK pm only — CLI pm has no equivalent (no Query object,
2866
- // no getContextUsage). OPT-IN per-chat or per-bot
2867
- // (rc.12+) — most chats don't want the noise. Per-chat takes
2864
+ // the threshold, post a quiet hint so the user knows /new
2865
+ // will help. SDK pm only — CLI pm has no equivalent (no
2866
+ // Query object, no getContextUsage). OPT-IN per-chat or
2867
+ // per-bot — most chats don't want the noise. Per-chat takes
2868
2868
  // precedence over per-bot so admins (Ivan DM) can opt in
2869
2869
  // without forcing it on every other chat.
2870
+ //
2871
+ // rc.56: threshold default lowered to 70% (was 85%) because
2872
+ // the SDK auto-compacts mid-turn at ~85% — by the time
2873
+ // polygram queries getContextUsage post-turn, the percentage
2874
+ // has already dropped and the hint never fires. 70% gives
2875
+ // the user 1-3 turns of headroom before SDK compaction.
2876
+ // Configurable via `contextHintThreshold` (number, 0-100)
2877
+ // per-chat or per-bot. Same precedence rule as contextHint.
2870
2878
  const chatCtxHint = chatConfig.contextHint != null
2871
2879
  ? chatConfig.contextHint
2872
2880
  : config.bot?.contextHint;
@@ -2874,8 +2882,13 @@ async function handleMessage(sessionKey, chatId, msg, bot) {
2874
2882
  const entry = pm.get(sessionKey);
2875
2883
  const q = entry?.query;
2876
2884
  if (q && typeof q.getContextUsage === 'function') {
2885
+ const threshold = chatConfig.contextHintThreshold != null
2886
+ ? chatConfig.contextHintThreshold
2887
+ : (config.bot?.contextHintThreshold != null
2888
+ ? config.bot.contextHintThreshold
2889
+ : undefined);
2877
2890
  q.getContextUsage().then((usage) => {
2878
- const text = maybeContextFullHint(usage);
2891
+ const text = maybeContextFullHint(usage, threshold != null ? { threshold } : undefined);
2879
2892
  if (!text) return;
2880
2893
  return tg(bot, 'sendMessage', {
2881
2894
  chat_id: chatId,