agenr 0.9.21 → 0.9.23

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.
@@ -3,19 +3,18 @@ import {
3
3
  SCOPE_LEVELS,
4
4
  checkAndFlagLowQuality,
5
5
  closeDb,
6
+ computeRecallFeedback,
6
7
  createLlmClient,
7
- embed,
8
8
  getDb,
9
9
  initDb,
10
10
  readConfig,
11
- resolveEmbeddingApiKey,
12
11
  runSimpleStream
13
- } from "../chunk-EY2VW6OI.js";
12
+ } from "../chunk-56GW7EIS.js";
14
13
  import {
15
14
  strengthenCoRecallEdges,
16
15
  toNumber,
17
16
  toStringValue
18
- } from "../chunk-QYZIPFIA.js";
17
+ } from "../chunk-RM5SLLEM.js";
19
18
 
20
19
  // src/openclaw-plugin/index.ts
21
20
  import { Type } from "@sinclair/typebox";
@@ -24,327 +23,6 @@ import os from "os";
24
23
  import path3 from "path";
25
24
  import { createInterface as createInterface2 } from "readline";
26
25
 
27
- // src/db/feedback.ts
28
- var RESPONSE_MIN_CHARS = 50;
29
- var RESPONSE_MAX_CHARS = 8e3;
30
- var SIGNAL_USED = 1;
31
- var SIGNAL_UNCLEAR = 0.4;
32
- var SIGNAL_CORRECTED = 0;
33
- var RESPONSE_USED_THRESHOLD = 0.5;
34
- var CORRECTION_THRESHOLD = 0.6;
35
- function isRecord(value) {
36
- return typeof value === "object" && value !== null;
37
- }
38
- function clamp01(value) {
39
- if (!Number.isFinite(value)) {
40
- return 0;
41
- }
42
- if (value <= 0) {
43
- return 0;
44
- }
45
- if (value >= 1) {
46
- return 1;
47
- }
48
- return value;
49
- }
50
- function mapBufferToVector(value) {
51
- if (value instanceof ArrayBuffer) {
52
- return Array.from(new Float32Array(value));
53
- }
54
- if (ArrayBuffer.isView(value)) {
55
- const view = value;
56
- return Array.from(
57
- new Float32Array(view.buffer, view.byteOffset, Math.floor(view.byteLength / Float32Array.BYTES_PER_ELEMENT))
58
- );
59
- }
60
- return [];
61
- }
62
- function cosineSimilarity(a, b) {
63
- const size = Math.min(a.length, b.length);
64
- if (size === 0) {
65
- return 0;
66
- }
67
- let dot = 0;
68
- let normA = 0;
69
- let normB = 0;
70
- for (let i = 0; i < size; i += 1) {
71
- const av = a[i] ?? 0;
72
- const bv = b[i] ?? 0;
73
- dot += av * bv;
74
- normA += av * av;
75
- normB += bv * bv;
76
- }
77
- if (normA <= 0 || normB <= 0) {
78
- return 0;
79
- }
80
- return dot / (Math.sqrt(normA) * Math.sqrt(normB));
81
- }
82
- function extractTextFromContent(content, separator) {
83
- if (typeof content === "string") {
84
- return content.trim();
85
- }
86
- if (!Array.isArray(content)) {
87
- return "";
88
- }
89
- const parts = [];
90
- for (const block of content) {
91
- if (!isRecord(block) || block.type !== "text") {
92
- continue;
93
- }
94
- const text = block.text;
95
- if (typeof text !== "string") {
96
- continue;
97
- }
98
- const trimmed = text.trim();
99
- if (trimmed) {
100
- parts.push(trimmed);
101
- }
102
- }
103
- return parts.join(separator).trim();
104
- }
105
- function collectAssistantText(messages) {
106
- const parts = [];
107
- for (const message of messages) {
108
- if (!isRecord(message) || message.role !== "assistant") {
109
- continue;
110
- }
111
- const text = extractTextFromContent(message.content, "\n");
112
- if (text) {
113
- parts.push(text);
114
- }
115
- }
116
- return parts.join("\n").trim();
117
- }
118
- function extractStoreContentsFromInput(input) {
119
- if (!isRecord(input)) {
120
- return [];
121
- }
122
- const out = [];
123
- const directContent = input.content;
124
- if (typeof directContent === "string" && directContent.trim()) {
125
- out.push(directContent.trim());
126
- }
127
- const entries = input.entries;
128
- if (Array.isArray(entries)) {
129
- for (const item of entries) {
130
- if (!isRecord(item)) {
131
- continue;
132
- }
133
- const content = item.content;
134
- if (typeof content === "string" && content.trim()) {
135
- out.push(content.trim());
136
- }
137
- }
138
- }
139
- return out;
140
- }
141
- function parseFunctionArguments(rawArgs) {
142
- if (isRecord(rawArgs)) {
143
- return rawArgs;
144
- }
145
- if (typeof rawArgs !== "string" || !rawArgs.trim()) {
146
- return null;
147
- }
148
- try {
149
- const parsed = JSON.parse(rawArgs);
150
- return isRecord(parsed) ? parsed : null;
151
- } catch {
152
- return null;
153
- }
154
- }
155
- function collectAgenrStoreContents(messages) {
156
- const contents = [];
157
- for (const message of messages) {
158
- if (!isRecord(message) || message.role !== "assistant") {
159
- continue;
160
- }
161
- const contentBlocks = message.content;
162
- if (Array.isArray(contentBlocks)) {
163
- for (const block of contentBlocks) {
164
- if (!isRecord(block) || block.type !== "tool_use" || block.name !== "agenr_store") {
165
- continue;
166
- }
167
- contents.push(...extractStoreContentsFromInput(block.input));
168
- }
169
- }
170
- const toolCalls = message.tool_calls;
171
- if (!Array.isArray(toolCalls)) {
172
- continue;
173
- }
174
- for (const toolCall of toolCalls) {
175
- if (!isRecord(toolCall)) {
176
- continue;
177
- }
178
- if (typeof toolCall.name === "string" && toolCall.name === "agenr_store") {
179
- const namedArgs = parseFunctionArguments(toolCall.arguments);
180
- if (namedArgs) {
181
- contents.push(...extractStoreContentsFromInput(namedArgs));
182
- } else {
183
- contents.push(...extractStoreContentsFromInput(toolCall.input));
184
- }
185
- continue;
186
- }
187
- const fn = toolCall.function;
188
- if (!isRecord(fn) || fn.name !== "agenr_store") {
189
- continue;
190
- }
191
- const args = parseFunctionArguments(fn.arguments);
192
- if (args) {
193
- contents.push(...extractStoreContentsFromInput(args));
194
- }
195
- }
196
- }
197
- return Array.from(new Set(contents));
198
- }
199
- async function fetchEmbeddedEntries(db, ids) {
200
- const idList = Array.from(ids).filter((id) => id.trim().length > 0);
201
- if (idList.length === 0) {
202
- return [];
203
- }
204
- const placeholders = idList.map(() => "?").join(", ");
205
- const result = await db.execute({
206
- sql: `
207
- SELECT id, embedding
208
- FROM entries
209
- WHERE id IN (${placeholders})
210
- AND embedding IS NOT NULL
211
- `,
212
- args: idList
213
- });
214
- const embeddedEntries = [];
215
- for (const row of result.rows) {
216
- const id = toStringValue(row.id);
217
- const embedding = mapBufferToVector(row.embedding);
218
- if (!id || embedding.length === 0) {
219
- continue;
220
- }
221
- embeddedEntries.push({ id, embedding });
222
- }
223
- return embeddedEntries;
224
- }
225
- async function updateQualityScores(db, updates) {
226
- if (updates.length === 0) {
227
- return;
228
- }
229
- const normalizedUpdates = /* @__PURE__ */ new Map();
230
- for (const update of updates) {
231
- const id = update.id.trim();
232
- if (!id) {
233
- continue;
234
- }
235
- normalizedUpdates.set(id, clamp01(update.signal));
236
- }
237
- if (normalizedUpdates.size === 0) {
238
- return;
239
- }
240
- const sql = `
241
- UPDATE entries
242
- SET quality_score = MIN(
243
- 1.0,
244
- MAX(
245
- 0.8 * COALESCE(quality_score, 0.5) + 0.2 * ?,
246
- CASE WHEN type IN ('fact', 'preference') THEN 0.35 ELSE 0.1 END
247
- )
248
- )
249
- WHERE id = ?
250
- `;
251
- await db.execute("BEGIN");
252
- try {
253
- for (const [id, signal] of normalizedUpdates.entries()) {
254
- await db.execute({ sql, args: [signal, id] });
255
- }
256
- await db.execute("COMMIT");
257
- } catch (error) {
258
- try {
259
- await db.execute("ROLLBACK");
260
- } catch {
261
- }
262
- throw error;
263
- }
264
- }
265
- async function computeRecallFeedback(db, sessionKey, messages, recalledEntryIds, config, logger) {
266
- const emptyResult = {
267
- usedIds: [],
268
- correctedIds: [],
269
- updatedIds: []
270
- };
271
- if (recalledEntryIds.size === 0) {
272
- return emptyResult;
273
- }
274
- const assistantText = collectAssistantText(messages);
275
- if (assistantText.length < RESPONSE_MIN_CHARS) {
276
- return emptyResult;
277
- }
278
- const responseCorpus = assistantText.slice(0, RESPONSE_MAX_CHARS);
279
- let apiKey;
280
- try {
281
- apiKey = resolveEmbeddingApiKey(config, process.env);
282
- } catch (error) {
283
- logger.warn(
284
- `[agenr] before_reset: feedback skipped for session=${sessionKey} - ${error instanceof Error ? error.message : String(error)}`
285
- );
286
- return emptyResult;
287
- }
288
- let responseEmbedding = null;
289
- try {
290
- const vectors = await embed([responseCorpus], apiKey);
291
- responseEmbedding = vectors[0] ?? null;
292
- } catch (error) {
293
- logger.warn(
294
- `[agenr] before_reset: feedback embedding failed for session=${sessionKey}: ${error instanceof Error ? error.message : String(error)}`
295
- );
296
- return emptyResult;
297
- }
298
- if (!responseEmbedding || responseEmbedding.length === 0) {
299
- return emptyResult;
300
- }
301
- const recalledEntries = await fetchEmbeddedEntries(db, recalledEntryIds);
302
- if (recalledEntries.length === 0) {
303
- return emptyResult;
304
- }
305
- const storeContents = collectAgenrStoreContents(messages);
306
- let correctionEmbeddings = [];
307
- if (storeContents.length > 0) {
308
- try {
309
- correctionEmbeddings = await embed(storeContents, apiKey);
310
- } catch (error) {
311
- logger.warn(
312
- `[agenr] before_reset: correction embedding failed for session=${sessionKey}: ${error instanceof Error ? error.message : String(error)}`
313
- );
314
- correctionEmbeddings = [];
315
- }
316
- }
317
- const correctedIds = /* @__PURE__ */ new Set();
318
- if (correctionEmbeddings.length > 0) {
319
- for (const entry of recalledEntries) {
320
- for (const correctionEmbedding of correctionEmbeddings) {
321
- if (cosineSimilarity(entry.embedding, correctionEmbedding) >= CORRECTION_THRESHOLD) {
322
- correctedIds.add(entry.id);
323
- break;
324
- }
325
- }
326
- }
327
- }
328
- const updates = recalledEntries.map((entry) => {
329
- if (correctedIds.has(entry.id)) {
330
- return { id: entry.id, signal: SIGNAL_CORRECTED };
331
- }
332
- const sim = cosineSimilarity(entry.embedding, responseEmbedding ?? []);
333
- return {
334
- id: entry.id,
335
- signal: sim >= RESPONSE_USED_THRESHOLD ? SIGNAL_USED : SIGNAL_UNCLEAR
336
- };
337
- });
338
- if (updates.length > 0) {
339
- await updateQualityScores(db, updates);
340
- }
341
- return {
342
- usedIds: updates.filter((update) => update.signal === SIGNAL_USED).map((update) => update.id),
343
- correctedIds: Array.from(correctedIds),
344
- updatedIds: updates.map((update) => update.id)
345
- };
346
- }
347
-
348
26
  // src/openclaw-plugin/mid-session-recall.ts
349
27
  var TRIVIAL_EXACT = /* @__PURE__ */ new Set([
350
28
  "yes",
@@ -404,6 +82,7 @@ var FALSE_POSITIVE_NOUNS = /* @__PURE__ */ new Set([
404
82
  "Who",
405
83
  "Which",
406
84
  "Can",
85
+ "Check",
407
86
  "Could",
408
87
  "Would",
409
88
  "Should",
@@ -436,6 +115,7 @@ var FALSE_POSITIVE_NOUNS = /* @__PURE__ */ new Set([
436
115
  "Thanks",
437
116
  "So",
438
117
  "Now",
118
+ "Really",
439
119
  "Well",
440
120
  "Still",
441
121
  "Yet",
@@ -456,6 +136,9 @@ var FALSE_POSITIVE_NOUNS = /* @__PURE__ */ new Set([
456
136
  "Her",
457
137
  "Its",
458
138
  "Their",
139
+ "She",
140
+ "They",
141
+ "You",
459
142
  "Some",
460
143
  "Any",
461
144
  "All",
@@ -659,15 +342,15 @@ function clearMidSessionStates() {
659
342
  function clearMidSessionState(key) {
660
343
  midSessionStates.delete(key.trim());
661
344
  }
662
- function isRecord2(value) {
345
+ function isRecord(value) {
663
346
  return typeof value === "object" && value !== null && !Array.isArray(value);
664
347
  }
665
348
  function toRecallRow(item) {
666
- if (!isRecord2(item)) {
349
+ if (!isRecord(item)) {
667
350
  return null;
668
351
  }
669
352
  const rawEntry = item["entry"];
670
- if (!isRecord2(rawEntry)) {
353
+ if (!isRecord(rawEntry)) {
671
354
  return null;
672
355
  }
673
356
  const subject = typeof rawEntry["subject"] === "string" ? rawEntry["subject"].trim() : "";
@@ -840,11 +523,11 @@ var RECENT_TURN_MAX_CHARS = 300;
840
523
  var SEMANTIC_SEED_PREVIOUS_TURNS_MAX_CHARS = 400;
841
524
  var DEFAULT_RECENT_TURN_LIMIT = 7;
842
525
  var CONVERSATION_METADATA_BLOCK_PATTERN = /(?:^|\r?\n)\s*Conversation info \(untrusted metadata\):\s*\r?\n\s*```json\s*\r?\n[\s\S]*?\r?\n\s*```\s*/g;
843
- function isRecord3(value) {
526
+ function isRecord2(value) {
844
527
  return typeof value === "object" && value !== null;
845
528
  }
846
529
  function extractTextFromUserMessage(message) {
847
- if (!isRecord3(message) || message["role"] !== "user") {
530
+ if (!isRecord2(message) || message["role"] !== "user") {
848
531
  return "";
849
532
  }
850
533
  const content = message["content"];
@@ -856,7 +539,7 @@ function extractTextFromUserMessage(message) {
856
539
  }
857
540
  const textParts = [];
858
541
  for (const part of content) {
859
- if (!isRecord3(part) || part["type"] !== "text") {
542
+ if (!isRecord2(part) || part["type"] !== "text") {
860
543
  continue;
861
544
  }
862
545
  const partText = part["text"];
@@ -871,7 +554,7 @@ function extractTextFromUserMessage(message) {
871
554
  return textParts.join(" ").trim();
872
555
  }
873
556
  function extractTextFromAssistantMessage(message) {
874
- if (!isRecord3(message) || message["role"] !== "assistant") {
557
+ if (!isRecord2(message) || message["role"] !== "assistant") {
875
558
  return "";
876
559
  }
877
560
  const content = message["content"];
@@ -883,7 +566,7 @@ function extractTextFromAssistantMessage(message) {
883
566
  }
884
567
  const textParts = [];
885
568
  for (const part of content) {
886
- if (!isRecord3(part) || part["type"] !== "text") {
569
+ if (!isRecord2(part) || part["type"] !== "text") {
887
570
  continue;
888
571
  }
889
572
  const partText = part["text"];
@@ -1039,7 +722,7 @@ async function extractRecentTurns(filePath, maxTurns = DEFAULT_RECENT_TURN_LIMIT
1039
722
  } catch {
1040
723
  return;
1041
724
  }
1042
- if (!isRecord3(record) || record["type"] !== "message") {
725
+ if (!isRecord2(record) || record["type"] !== "message") {
1043
726
  return;
1044
727
  }
1045
728
  const message = record["message"];
@@ -1233,7 +916,7 @@ function resolveWarn(pluginConfig) {
1233
916
  }
1234
917
  }
1235
918
  return (message) => {
1236
- console.warn(message);
919
+ console.warn(`[AGENR] ${message}`);
1237
920
  };
1238
921
  }
1239
922
  function sourceStringFromEntry(entry) {
@@ -1608,7 +1291,7 @@ var MAX_RECALLED_SESSIONS = 200;
1608
1291
  var DEFAULT_MID_SESSION_RECALL_LIMIT = 8;
1609
1292
  var DEFAULT_MID_SESSION_QUERY_SIMILARITY_THRESHOLD = 0.85;
1610
1293
  var DEFAULT_STORE_NUDGE_THRESHOLD = 8;
1611
- var DEFAULT_STORE_NUDGE_MAX_PER_SESSION = 3;
1294
+ var DEFAULT_STORE_NUDGE_MAX_PER_SESSION = 5;
1612
1295
  var sessionRecalledEntries = /* @__PURE__ */ new Map();
1613
1296
  var sessionRef = { current: "" };
1614
1297
  function isDebugEnabled(config) {
@@ -1616,7 +1299,7 @@ function isDebugEnabled(config) {
1616
1299
  }
1617
1300
  function debugLog(enabled, tag, message) {
1618
1301
  if (enabled) {
1619
- console.error(`[${tag}] ${message}`);
1302
+ console.error(`[AGENR:${tag}] ${message}`);
1620
1303
  }
1621
1304
  }
1622
1305
  var sessionSignalState = /* @__PURE__ */ new Map();
@@ -1840,10 +1523,10 @@ env states, config values. Do NOT repeat decisions already in KEY
1840
1523
  FINDINGS. Write "None" if nothing new.
1841
1524
 
1842
1525
  Keep the total response under 500 words. Plain text only.`;
1843
- function isRecord4(value) {
1526
+ function isRecord3(value) {
1844
1527
  return typeof value === "object" && value !== null;
1845
1528
  }
1846
- function extractTextFromContent2(content, separator) {
1529
+ function extractTextFromContent(content, separator) {
1847
1530
  if (typeof content === "string") {
1848
1531
  return content.trim();
1849
1532
  }
@@ -1852,7 +1535,7 @@ function extractTextFromContent2(content, separator) {
1852
1535
  }
1853
1536
  const textParts = [];
1854
1537
  for (const block of content) {
1855
- if (!isRecord4(block) || block["type"] !== "text") {
1538
+ if (!isRecord3(block) || block["type"] !== "text") {
1856
1539
  continue;
1857
1540
  }
1858
1541
  const blockText = block["text"];
@@ -1867,7 +1550,7 @@ function extractTextFromContent2(content, separator) {
1867
1550
  return textParts.join(separator).trim();
1868
1551
  }
1869
1552
  function extractHandoffContent(content) {
1870
- return extractTextFromContent2(content, " ");
1553
+ return extractTextFromContent(content, " ");
1871
1554
  }
1872
1555
  function stripInjectedContext(text) {
1873
1556
  if (!text) {
@@ -1918,7 +1601,7 @@ async function readSessionsJson(sessionsDir) {
1918
1601
  const sessionsJsonPath = path3.join(sessionsDir, "sessions.json");
1919
1602
  const raw = await fs.promises.readFile(sessionsJsonPath, "utf8");
1920
1603
  const parsed = JSON.parse(raw);
1921
- return isRecord4(parsed) ? parsed : {};
1604
+ return isRecord3(parsed) ? parsed : {};
1922
1605
  } catch {
1923
1606
  return {};
1924
1607
  }
@@ -1947,7 +1630,7 @@ function getSurfaceForSessionFile(sessionFilePath, sessionsJson) {
1947
1630
  try {
1948
1631
  const normalizedTarget = path3.resolve(sessionFilePath);
1949
1632
  for (const value of Object.values(sessionsJson)) {
1950
- if (!isRecord4(value)) {
1633
+ if (!isRecord3(value)) {
1951
1634
  continue;
1952
1635
  }
1953
1636
  const entrySessionFile = value["sessionFile"];
@@ -1957,12 +1640,12 @@ function getSurfaceForSessionFile(sessionFilePath, sessionsJson) {
1957
1640
  if (path3.resolve(entrySessionFile) !== normalizedTarget) {
1958
1641
  continue;
1959
1642
  }
1960
- const origin = isRecord4(value["origin"]) ? value["origin"] : null;
1643
+ const origin = isRecord3(value["origin"]) ? value["origin"] : null;
1961
1644
  const originSurface = origin && typeof origin["surface"] === "string" ? origin["surface"].trim() : "";
1962
1645
  if (originSurface) {
1963
1646
  return originSurface;
1964
1647
  }
1965
- const deliveryContext = isRecord4(value["deliveryContext"]) ? value["deliveryContext"] : null;
1648
+ const deliveryContext = isRecord3(value["deliveryContext"]) ? value["deliveryContext"] : null;
1966
1649
  const channel = deliveryContext && typeof deliveryContext["channel"] === "string" ? deliveryContext["channel"].trim() : "";
1967
1650
  return channel || "prior session";
1968
1651
  }
@@ -1989,11 +1672,11 @@ async function readMessagesFromJsonl(filePath) {
1989
1672
  } catch {
1990
1673
  continue;
1991
1674
  }
1992
- if (!isRecord4(parsed) || parsed["type"] !== "message") {
1675
+ if (!isRecord3(parsed) || parsed["type"] !== "message") {
1993
1676
  continue;
1994
1677
  }
1995
1678
  const message = parsed["message"];
1996
- if (!isRecord4(message)) {
1679
+ if (!isRecord3(message)) {
1997
1680
  continue;
1998
1681
  }
1999
1682
  const role = message["role"];
@@ -2105,13 +1788,13 @@ function capTranscriptLength(params) {
2105
1788
  return transcript;
2106
1789
  }
2107
1790
  function extractAssistantSummaryText(message) {
2108
- if (!isRecord4(message)) {
1791
+ if (!isRecord3(message)) {
2109
1792
  return "";
2110
1793
  }
2111
- return extractTextFromContent2(message["content"], "\n");
1794
+ return extractTextFromContent(message["content"], "\n");
2112
1795
  }
2113
1796
  function mapCurrentSessionMessage(message) {
2114
- if (!isRecord4(message)) {
1797
+ if (!isRecord3(message)) {
2115
1798
  return null;
2116
1799
  }
2117
1800
  const role = message["role"];
@@ -2271,7 +1954,7 @@ async function summarizeSessionForHandoff(currentRawMessages, sessionsDir, curre
2271
1954
  debugLog(debugEnabled, "handoff", `logged LLM request/response to ${normalizedLogDir}`);
2272
1955
  } catch (err) {
2273
1956
  console.error(
2274
- `[agenr] handoff: failed to write LLM request/response logs: ${err instanceof Error ? err.message : String(err)}`
1957
+ `[AGENR:handoff] failed to write LLM request/response logs: ${err instanceof Error ? err.message : String(err)}`
2275
1958
  );
2276
1959
  }
2277
1960
  }
@@ -2279,7 +1962,7 @@ async function summarizeSessionForHandoff(currentRawMessages, sessionsDir, curre
2279
1962
  return summaryText;
2280
1963
  } catch (err) {
2281
1964
  console.error(
2282
- `[agenr] before_reset: summarize handoff failed: ${err instanceof Error ? err.message : String(err)}`
1965
+ `[AGENR:before_reset] summarize handoff failed: ${err instanceof Error ? err.message : String(err)}`
2283
1966
  );
2284
1967
  return null;
2285
1968
  }
@@ -2326,7 +2009,7 @@ async function retireFallbackHandoffEntries(params) {
2326
2009
  }
2327
2010
  const retirePromises = [];
2328
2011
  for (const item of browseResult.results) {
2329
- const entryRecord = isRecord4(item.entry) ? item.entry : null;
2012
+ const entryRecord = isRecord3(item.entry) ? item.entry : null;
2330
2013
  if (!entryRecord) {
2331
2014
  continue;
2332
2015
  }
@@ -2368,13 +2051,13 @@ async function retireFallbackHandoffEntries(params) {
2368
2051
  }
2369
2052
  function normalizeHandoffMessages(messages) {
2370
2053
  return messages.map((message) => {
2371
- if (!isRecord4(message)) {
2054
+ if (!isRecord3(message)) {
2372
2055
  return message;
2373
2056
  }
2374
2057
  if (message["role"] === "user" || message["role"] === "assistant") {
2375
2058
  return message;
2376
2059
  }
2377
- if (message["type"] !== "message" || !isRecord4(message["message"])) {
2060
+ if (message["type"] !== "message" || !isRecord3(message["message"])) {
2378
2061
  return message;
2379
2062
  }
2380
2063
  const parsedMessage = { ...message["message"] };
@@ -2425,7 +2108,7 @@ async function runHandoffForSession(opts) {
2425
2108
  debugLog(Boolean(opts.debugEnabled), opts.source, "fallback handoff stored");
2426
2109
  } catch (err) {
2427
2110
  console.error(
2428
- `[agenr] ${opts.source}: fallback store failed: ${err instanceof Error ? err.message : String(err)}`
2111
+ `[AGENR:${opts.source}] fallback store failed: ${err instanceof Error ? err.message : String(err)}`
2429
2112
  );
2430
2113
  fallbackEntrySubject = null;
2431
2114
  }
@@ -2479,7 +2162,7 @@ async function runHandoffForSession(opts) {
2479
2162
  debugLog(Boolean(opts.debugEnabled), opts.source, "LLM handoff stored");
2480
2163
  } catch (err) {
2481
2164
  console.error(
2482
- `[agenr] ${opts.source}: LLM handoff store failed: ${err instanceof Error ? err.message : String(err)}`
2165
+ `[AGENR:${opts.source}] LLM handoff store failed: ${err instanceof Error ? err.message : String(err)}`
2483
2166
  );
2484
2167
  }
2485
2168
  }
@@ -2602,7 +2285,7 @@ var plugin = {
2602
2285
  debugLog(debug, "session-start", "runHandoffForSession completed");
2603
2286
  } catch (err) {
2604
2287
  console.error(
2605
- `[agenr] session_start: handoff failed: ${err instanceof Error ? err.message : String(err)}`
2288
+ `[AGENR:session_start] handoff failed: ${err instanceof Error ? err.message : String(err)}`
2606
2289
  );
2607
2290
  }
2608
2291
  }
@@ -2654,7 +2337,7 @@ var plugin = {
2654
2337
  debugLog(debug, "session-start", `retired handoff ${entryId}`);
2655
2338
  }).catch((err) => {
2656
2339
  console.error(
2657
- `[agenr] session-start: retire handoff ${entryId} failed: ${err instanceof Error ? err.message : String(err)}`
2340
+ `[AGENR:session-start] retire handoff ${entryId} failed: ${err instanceof Error ? err.message : String(err)}`
2658
2341
  );
2659
2342
  })
2660
2343
  );
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "agenr",
3
- "version": "0.9.21",
3
+ "version": "0.9.23",
4
4
  "openclaw": {
5
5
  "extensions": [
6
6
  "dist/openclaw-plugin/index.js"