clawgram 2.7.1 → 2.8.1

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.
package/dist/channel.js CHANGED
@@ -233,6 +233,31 @@ const createChannelPlugin = (runtimes, pluginRuntime) => {
233
233
  },
234
234
  capabilities: CHANNEL_CAPABILITIES,
235
235
  agentPrompt: {
236
+ // Core injects its `## Reactions` section only when this returns a
237
+ // level. Without it the prompt never mentions reactions, and the agent
238
+ // treats the `react` action as one more entry in a 106-property schema:
239
+ // she used it when asked outright in a DM and never once on her own.
240
+ reactionGuidance: ({ cfg, accountId }) => {
241
+ const resolvedAccountId = (0, helpers_1.resolveConfiguredAccountId)(cfg, accountId);
242
+ const account = resolvedAccountId
243
+ ? cfg?.channels?.[constants_1.CHANNEL_ID]?.accounts?.[resolvedAccountId]
244
+ : undefined;
245
+ const level = (0, reactions_1.resolveAgentReactionGuidance)(account?.reactionLevel);
246
+ // Logged because "the hook returns the right thing" and "the prompt
247
+ // gained a Reactions section" turned out to be different questions:
248
+ // on 2.8.0 the first was verifiable by hand on the server while the
249
+ // prompt stayed byte-identical. Without this line there is no way to
250
+ // tell a hook core never calls from a hook that answers undefined.
251
+ actionLog.info("clawgram reactionGuidance", {
252
+ accountId: resolvedAccountId ?? null,
253
+ requestedAccountId: accountId ?? null,
254
+ configuredLevel: typeof account?.reactionLevel === "string" ? account.reactionLevel : null,
255
+ level: level ?? null,
256
+ });
257
+ // "clawgram" is our plugin id; the section reads "Reactions are
258
+ // enabled for <label>", and the label is the platform people see.
259
+ return level ? { level, channelLabel: "Telegram" } : undefined;
260
+ },
236
261
  messageToolHints: () => [
237
262
  "Use clawgram to send Telegram replies from the connected personal account.",
238
263
  "When replying in the current Telegram chat, omit `to`/`target` and clawgram will send to the current conversation automatically.",
package/dist/reactions.js CHANGED
@@ -11,7 +11,47 @@
11
11
  * tested without a Telegram connection.
12
12
  */
13
13
  Object.defineProperty(exports, "__esModule", { value: true });
14
+ exports.resolveAgentReactionGuidance = resolveAgentReactionGuidance;
14
15
  exports.parseReactionParams = parseReactionParams;
16
+ /**
17
+ * How chatty the agent may be with reactions, as core understands it.
18
+ *
19
+ * Core injects a `## Reactions` section into the system prompt only when a
20
+ * channel returns a level from `agentPrompt.reactionGuidance`. Return nothing
21
+ * and the prompt never mentions reactions at all — which is what happened
22
+ * here until 2.8.0: the `react` action existed, the agent had it, and no line
23
+ * of the prompt suggested using it.
24
+ *
25
+ * Levels and fallbacks mirror the bundled Telegram channel so the two behave
26
+ * the same for the same config:
27
+ *
28
+ * - `off`, `ack` — no agent reactions (`ack` is the "seen it" emoji core sends
29
+ * by itself, which is a different feature);
30
+ * - `minimal` — react sparingly; the default when nothing is configured;
31
+ * - `extensive` — react whenever it feels natural.
32
+ *
33
+ * An invalid value yields no guidance rather than a guess: a typo turning a
34
+ * work chat chatty is worse than a typo turning it quiet.
35
+ */
36
+ function resolveAgentReactionGuidance(value) {
37
+ if (value === undefined || value === null) {
38
+ return "minimal";
39
+ }
40
+ if (typeof value !== "string") {
41
+ return undefined;
42
+ }
43
+ const level = value.trim();
44
+ if (!level) {
45
+ return "minimal";
46
+ }
47
+ if (level === "minimal" || level === "extensive") {
48
+ return level;
49
+ }
50
+ if (level === "off" || level === "ack") {
51
+ return undefined;
52
+ }
53
+ return undefined;
54
+ }
15
55
  /** Accepts the boolean and the string a JSON-ish caller may send for it. */
16
56
  function readBooleanFlag(value) {
17
57
  return value === true || value === "true";
@@ -2,7 +2,7 @@
2
2
  "id": "clawgram",
3
3
  "name": "Clawgram",
4
4
  "description": "Clawgram — personal Telegram (MTProto userbot) channel for OpenClaw. Your AI assistant reads and responds as you.",
5
- "version": "2.7.1",
5
+ "version": "2.8.1",
6
6
  "configSchema": {
7
7
  "type": "object",
8
8
  "additionalProperties": false,
@@ -326,6 +326,16 @@
326
326
  "type": "string",
327
327
  "description": "Where joins observed for this account are journalled. Defaults to a per-account file under the OpenClaw state directory."
328
328
  },
329
+ "reactionLevel": {
330
+ "type": "string",
331
+ "enum": [
332
+ "off",
333
+ "ack",
334
+ "minimal",
335
+ "extensive"
336
+ ],
337
+ "description": "How freely the agent may leave emoji reactions (2.8.0). Core injects its `## Reactions` prompt section only for `minimal` and `extensive`; `off` and `ack` leave the prompt silent about reactions, and the agent then effectively never reacts on its own. Absent means `minimal`. Mirrors the bundled Telegram channel's reactionLevel."
338
+ },
329
339
  "replyParseMode": {
330
340
  "type": "string",
331
341
  "enum": [
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "clawgram",
3
- "version": "2.7.1",
3
+ "version": "2.8.1",
4
4
  "description": "Clawgram — personal Telegram (MTProto userbot) channel for OpenClaw. Your AI assistant reads and responds as you.",
5
5
  "main": "./dist/index.js",
6
6
  "scripts": {