polygram 0.8.0-rc.28 โ†’ 0.8.0-rc.29

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.28",
4
+ "version": "0.8.0-rc.29",
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",
@@ -195,6 +195,7 @@ class ProcessManagerSdk {
195
195
  onAssistantMessageStart = null,
196
196
  onCompactBoundary = null,
197
197
  onQueueDrop = null,
198
+ onThinking = null,
198
199
  queryCloseTimeoutMs = DEFAULT_QUERY_CLOSE_TIMEOUT_MS,
199
200
  } = {}) {
200
201
  if (!spawnFn) throw new Error('spawnFn required');
@@ -212,6 +213,7 @@ class ProcessManagerSdk {
212
213
  this.onAssistantMessageStart = onAssistantMessageStart;
213
214
  this.onCompactBoundary = onCompactBoundary;
214
215
  this.onQueueDrop = onQueueDrop;
216
+ this.onThinking = onThinking;
215
217
  this.procs = new Map(); // sessionKey โ†’ entry
216
218
  this._lruWaiters = []; // [{ resolve, reject, timer }]
217
219
  }
@@ -380,6 +382,31 @@ class ProcessManagerSdk {
380
382
  return;
381
383
  }
382
384
 
385
+ // rc.29: stream_event with content_block_start of type='thinking'.
386
+ // Fires DURING extended-thinking phase, BEFORE any text or tool_use
387
+ // content appears. Without this, polygram's reactor stays at QUEUED
388
+ // (๐Ÿ‘€) for the full thinking duration (10+ s with effort=high),
389
+ // then transitions THINKING โ†’ CODING in <1s when the model finally
390
+ // emits text/tool. UX target: ๐Ÿ‘€ โ†’ ๐Ÿค” transition fires within
391
+ // 100-500ms of pm.send, matching Claude Code CLI's "Thinking..."
392
+ // spinner timing.
393
+ //
394
+ // Requires `includePartialMessages: true` in SdkOptions; without
395
+ // it, this branch is unreachable (we never receive stream_event).
396
+ if (msg.type === 'stream_event' && head && !head.thinkingFired) {
397
+ const ev = msg.event;
398
+ const isThinkingStart = ev?.type === 'content_block_start'
399
+ && ev?.content_block?.type === 'thinking';
400
+ if (isThinkingStart) {
401
+ head.thinkingFired = true;
402
+ if (this.onThinking) {
403
+ try { this.onThinking(entry.sessionKey, entry); }
404
+ catch (err) { this.logger.error?.(`[${entry.label}] onThinking: ${err.message}`); }
405
+ }
406
+ }
407
+ return;
408
+ }
409
+
383
410
  if (msg.type === 'system' && msg.subtype === 'compact_boundary') {
384
411
  // D6 / ยง5: surface compaction boundary to caller. Sequencing
385
412
  // guarantee โ€” we await this callback before processing the
@@ -587,6 +614,7 @@ class ProcessManagerSdk {
587
614
  prompt,
588
615
  transientRetries: 0,
589
616
  firstAssistantSeen: false,
617
+ thinkingFired: false, // rc.29: extended-thinking โ†’ reactor THINKING
590
618
  };
591
619
 
592
620
  pending.fireFirstStream = () => {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "polygram",
3
- "version": "0.8.0-rc.28",
3
+ "version": "0.8.0-rc.29",
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
@@ -959,6 +959,14 @@ function buildSdkOptions(sessionKey, ctx) {
959
959
  permissionMode: useCanUseTool ? 'default' : 'bypassPermissions',
960
960
  allowDangerouslySkipPermissions: !useCanUseTool,
961
961
  ...(useCanUseTool && { canUseTool: makeCanUseTool(sessionKey) }),
962
+ // rc.29: enable partial messages so pm-sdk can detect thinking
963
+ // blocks during the extended-thinking phase (before any text or
964
+ // tool_use arrives). Without this, the reactor stays at ๐Ÿ‘€ for
965
+ // the full thinking duration. With this, pm-sdk's onThinking
966
+ // callback fires within ~100-500ms of pm.send, giving the user
967
+ // a fast ๐Ÿ‘€ โ†’ ๐Ÿค” transition matching Claude Code CLI's
968
+ // "Thinking..." spinner.
969
+ includePartialMessages: true,
962
970
  hooks: {
963
971
  PostToolBatch: [{ hooks: [postToolBatchHook] }],
964
972
  ...(sessionStartHook && {
@@ -3584,6 +3592,20 @@ async function main() {
3584
3592
  const r = head?.context?.reactor;
3585
3593
  if (r && typeof r.heartbeat === 'function') r.heartbeat();
3586
3594
  },
3595
+ // rc.29: extended-thinking โ†’ ๐Ÿค” transition. Fires the moment the
3596
+ // model's first content_block_start with type='thinking' arrives
3597
+ // via stream_event. Pre-rc.29 we waited for first text/tool_use,
3598
+ // which under effort=high means the reactor sat at ๐Ÿ‘€ for 10+ s
3599
+ // before flipping. Now the user sees ๐Ÿ‘€ โ†’ ๐Ÿค” within ~100-500ms
3600
+ // of pm.send, matching Claude Code CLI's "Thinking..." UX.
3601
+ onThinking: (sessionKey, entry) => {
3602
+ const head = entry.pendingQueue?.[0];
3603
+ const r = head?.context?.reactor;
3604
+ if (r && typeof r.setState === 'function') r.setState('THINKING');
3605
+ logEvent('thinking-started', {
3606
+ chat_id: entry.chatId, session_key: sessionKey,
3607
+ });
3608
+ },
3587
3609
  // 0.8.0 Phase 2 step 5: SDK auto-compaction observability. Fires
3588
3610
  // when SDK emits SDKCompactBoundaryMessage (between turns or
3589
3611
  // mid-turn โ€” see Phase 0 gate 8.5). Surfaces a quiet system