polygram 0.8.0-rc.2 → 0.8.0-rc.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.
@@ -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.2",
4
+ "version": "0.8.0-rc.3",
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",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "polygram",
3
- "version": "0.8.0-rc.2",
3
+ "version": "0.8.0-rc.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": {
package/polygram.js CHANGED
@@ -1709,16 +1709,34 @@ async function handleConfigCallback(ctx) {
1709
1709
  user: cmdUser, user_id: cmdUserId, source: 'inline-button',
1710
1710
  }), `log ${setting} change`);
1711
1711
 
1712
- // Graceful respawn of the topic's session that the card is in. With
1712
+ // Graceful application of the change to the topic's session. With
1713
1713
  // isolateTopics=false sessionKey is the chat (one shared session). With
1714
1714
  // isolateTopics=true sessionKey carries the topic, so other topics'
1715
1715
  // in-flight turns are not disturbed and the card update + button toast
1716
- // only affect the user's own context. Mirrors the text-command flow in
1717
- // handleMessage's requestRespawnForSession.
1716
+ // only affect the user's own context.
1717
+ //
1718
+ // CLI pm: requestRespawn drains pending turns then kills the process;
1719
+ // the next user message spawns fresh with the updated chatConfig.
1720
+ // SDK pm: applies live to the running Query via setModel /
1721
+ // applyFlagSettings — no respawn needed, change takes effect for the
1722
+ // rest of the in-flight turn AND all future ones. Falls back to
1723
+ // {killed: false} if neither method is available, leaving the new
1724
+ // chatConfig value to be picked up by the next cold spawn.
1718
1725
  const callbackThreadId = ctx.callbackQuery.message?.message_thread_id?.toString() || null;
1719
1726
  const callbackSessionKey = getSessionKey(chatId, callbackThreadId, chatConfig);
1720
1727
  const reason = setting === 'model' ? 'model-change' : 'effort-change';
1721
- const respawn = pm.requestRespawn(callbackSessionKey, reason);
1728
+ let respawn;
1729
+ if (typeof pm.requestRespawn === 'function') {
1730
+ respawn = pm.requestRespawn(callbackSessionKey, reason);
1731
+ } else if (setting === 'effort' && typeof pm.applyFlagSettings === 'function') {
1732
+ const ok = await pm.applyFlagSettings(callbackSessionKey, { effortLevel: value });
1733
+ respawn = { killed: ok };
1734
+ } else if (setting === 'model' && typeof pm.setModel === 'function') {
1735
+ const ok = await pm.setModel(callbackSessionKey, value);
1736
+ respawn = { killed: ok };
1737
+ } else {
1738
+ respawn = { killed: false };
1739
+ }
1722
1740
  const anyActive = !respawn.killed;
1723
1741
 
1724
1742
  // Re-render the card with updated ✓ + the same help text shown initially.
@@ -1969,17 +1987,33 @@ async function handleMessage(sessionKey, chatId, msg, bot) {
1969
1987
  }
1970
1988
  return;
1971
1989
  }
1972
- // Graceful respawn of the user's CURRENT session only. With
1973
- // isolateTopics=false the sessionKey is just the chat (one shared
1974
- // session for the whole chat — every topic respawns implicitly).
1975
- // With isolateTopics=true each topic is a separate session, and a
1976
- // /model in topic A should NOT disturb topic B's in-flight turn or
1977
- // post a phantom "✓ Using sonnet now" in a topic that didn't ask.
1978
- // Pre-0.6.5 this iterated pm.keys() by chat prefix and incorrectly
1979
- // fanned out across all topics under isolateTopics=true.
1980
- const requestRespawnForSession = (reason) => {
1981
- const res = pm.requestRespawn(sessionKey, reason);
1982
- return { queued: res.queued, anyActive: !res.killed };
1990
+ // Graceful application of a model/effort change to the user's CURRENT
1991
+ // session only. With isolateTopics=false the sessionKey is just the
1992
+ // chat (one shared session for the whole chat — every topic
1993
+ // respawns implicitly). With isolateTopics=true each topic is a
1994
+ // separate session, and a /model in topic A should NOT disturb
1995
+ // topic B's in-flight turn or post a phantom "✓ Using sonnet now"
1996
+ // in a topic that didn't ask.
1997
+ //
1998
+ // CLI pm: requestRespawn drains pending turns then kills the process;
1999
+ // the next user message spawns fresh with the updated chatConfig.
2000
+ // SDK pm: applies live to the running Query via setModel /
2001
+ // applyFlagSettings — no respawn needed, change takes effect for
2002
+ // the rest of the in-flight turn AND all future ones.
2003
+ const applyConfigChange = async (reason, setting, value) => {
2004
+ if (typeof pm.requestRespawn === 'function') {
2005
+ const res = pm.requestRespawn(sessionKey, reason);
2006
+ return { queued: res.queued, anyActive: !res.killed };
2007
+ }
2008
+ if (setting === 'effort' && typeof pm.applyFlagSettings === 'function') {
2009
+ const ok = await pm.applyFlagSettings(sessionKey, { effortLevel: value });
2010
+ return { queued: 0, anyActive: !ok };
2011
+ }
2012
+ if (setting === 'model' && typeof pm.setModel === 'function') {
2013
+ const ok = await pm.setModel(sessionKey, value);
2014
+ return { queued: 0, anyActive: !ok };
2015
+ }
2016
+ return { queued: 0, anyActive: false };
1983
2017
  };
1984
2018
 
1985
2019
  if (botAllowsCommands && text.startsWith('/model ')) {
@@ -1993,7 +2027,7 @@ async function handleMessage(sessionKey, chatId, msg, bot) {
1993
2027
  old_value: oldModel, new_value: newModel,
1994
2028
  user: cmdUser, user_id: cmdUserId, source: 'command',
1995
2029
  }), 'log model change');
1996
- const { anyActive } = requestRespawnForSession('model-change');
2030
+ const { anyActive } = await applyConfigChange('model-change', 'model', newModel);
1997
2031
  const ver = MODEL_VERSIONS[newModel] || newModel;
1998
2032
  const suffix = anyActive ? ` — I'll switch when I finish` : '';
1999
2033
  await sendReply(`Model → ${newModel} (${ver})${suffix}`);
@@ -2013,7 +2047,7 @@ async function handleMessage(sessionKey, chatId, msg, bot) {
2013
2047
  old_value: oldEffort, new_value: newEffort,
2014
2048
  user: cmdUser, user_id: cmdUserId, source: 'command',
2015
2049
  }), 'log effort change');
2016
- const { anyActive } = requestRespawnForSession('effort-change');
2050
+ const { anyActive } = await applyConfigChange('effort-change', 'effort', newEffort);
2017
2051
  const suffix = anyActive ? ` — I'll switch when I finish` : '';
2018
2052
  await sendReply(`Effort → ${newEffort}${suffix}`);
2019
2053
  } else {