agenr 3.0.0 → 3.2.0

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.
@@ -21,8 +21,9 @@ import {
21
21
  readNumber,
22
22
  readOptionalString,
23
23
  readRequiredString,
24
+ truncate,
24
25
  validateTemporalValidityRange
25
- } from "./chunk-ELR2HSVC.js";
26
+ } from "./chunk-FMQTRTWE.js";
26
27
  import {
27
28
  compactClaimKey,
28
29
  describeClaimKeyNormalizationFailure,
@@ -36,6 +37,166 @@ import {
36
37
  validateExtractedClaimKey
37
38
  } from "./chunk-5LADPJ4C.js";
38
39
 
40
+ // src/adapters/shared/errors.ts
41
+ function formatErrorMessage(error) {
42
+ return error instanceof Error ? error.message : String(error);
43
+ }
44
+
45
+ // src/adapters/shared/resolve-target.ts
46
+ function buildEntryMemoryResolverPorts(services) {
47
+ return {
48
+ getEntryById: async (entryId) => await services.entries.getEntry(entryId) ?? (await services.memory.getEntryTrace(entryId))?.entry ?? null,
49
+ findEntryBySubject: async (subject) => services.memory.findEntryBySubject(subject),
50
+ findMostRecentEntry: async () => services.memory.findMostRecentEntry()
51
+ };
52
+ }
53
+ async function resolveTargetEntry(ports, params, options = {}) {
54
+ const id = readOptionalStringParam(params, "id");
55
+ const subject = readOptionalStringParam(params, "subject");
56
+ const last = options.allowLast ? readBooleanParam(params, "last") : void 0;
57
+ const selectorCount = (id ? 1 : 0) + (subject ? 1 : 0) + (last === true ? 1 : 0);
58
+ const selectorDescription = options.allowLast ? "id, subject, or last" : "id or subject";
59
+ if (selectorCount !== 1) {
60
+ throw new Error(`Provide exactly one target selector: ${selectorDescription}.`);
61
+ }
62
+ if (last) {
63
+ const entry2 = await ports.findMostRecentEntry();
64
+ if (!entry2) {
65
+ throw new Error("No agenr entries exist yet.");
66
+ }
67
+ return entry2;
68
+ }
69
+ if (id) {
70
+ const entry2 = await ports.getEntryById(id);
71
+ if (!entry2) {
72
+ throw new Error(`No agenr entry found for id ${id}.`);
73
+ }
74
+ return entry2;
75
+ }
76
+ const entry = await ports.findEntryBySubject(subject ?? "");
77
+ if (!entry) {
78
+ throw new Error(`No agenr entry found for subject "${subject}".`);
79
+ }
80
+ return entry;
81
+ }
82
+ function readBooleanParam(params, key) {
83
+ const value = params[key];
84
+ if (value === void 0) {
85
+ return void 0;
86
+ }
87
+ if (typeof value === "boolean") {
88
+ return value;
89
+ }
90
+ throw new Error(`${key} must be a boolean.`);
91
+ }
92
+ function readOptionalStringParam(params, key) {
93
+ const value = params[key];
94
+ if (value === void 0 || value === null) {
95
+ return void 0;
96
+ }
97
+ if (typeof value !== "string") {
98
+ throw new Error(`${key} must be a string.`);
99
+ }
100
+ const normalized = value.trim();
101
+ return normalized.length > 0 ? normalized : void 0;
102
+ }
103
+
104
+ // src/adapters/shared/entry-tools.ts
105
+ var ENTRY_TYPE_DESCRIPTION = "Knowledge type to store. Use fact for durable truth about a person, system, place, or how something works. Use decision for a standing rule, constraint, policy, or chosen approach future sessions should follow - not a progress update or completed action. Use preference for what someone likes, wants, values, or wants avoided. Use lesson for a non-obvious takeaway learned from experience that should change future behavior. Use milestone for a rare one-time event with durable future significance - not ordinary execution progress. Use relationship for a meaningful durable connection between people, groups, or systems.";
106
+ var EXPIRY_DESCRIPTION = "Lifetime bucket: core (always injected at session start, use sparingly), permanent (durable and recalled on demand), or temporary (short-horizon).";
107
+ var UPDATE_EXPIRY_DESCRIPTION = `${EXPIRY_DESCRIPTION} Accepted values: ${EXPIRY_LEVELS.join(", ")}.`;
108
+ var RECALL_MODES = ["auto", "entries", "episodes", "procedures"];
109
+ function asRecord(value) {
110
+ if (typeof value === "object" && value !== null && !Array.isArray(value)) {
111
+ return value;
112
+ }
113
+ throw new Error("Tool parameters must be an object.");
114
+ }
115
+ function parseExpiry(value) {
116
+ if (value === void 0) {
117
+ return void 0;
118
+ }
119
+ if (EXPIRY_LEVELS.includes(value)) {
120
+ return value;
121
+ }
122
+ throw new Error(`Unsupported expiry "${value}".`);
123
+ }
124
+ function parseEntryTypes(values) {
125
+ return normalizeStringArray(values).map((value) => parseEntryType(value));
126
+ }
127
+ function parseEntryType(value) {
128
+ if (ENTRY_TYPES.includes(value)) {
129
+ return value;
130
+ }
131
+ throw new Error(`Unsupported entry type "${value}".`);
132
+ }
133
+ function parseRecallMode(value) {
134
+ if (value === void 0) {
135
+ return void 0;
136
+ }
137
+ if (RECALL_MODES.includes(value)) {
138
+ return value;
139
+ }
140
+ throw new Error(`Unsupported recall mode "${value}".`);
141
+ }
142
+ function normalizeStringArray(values) {
143
+ if (!values) {
144
+ return [];
145
+ }
146
+ return Array.from(new Set(values.map((value) => value.trim()).filter((value) => value.length > 0)));
147
+ }
148
+ function formatTargetSelector(id, subject, last) {
149
+ if (last === true) {
150
+ return "last";
151
+ }
152
+ if (id) {
153
+ return `id:${JSON.stringify(id)}`;
154
+ }
155
+ if (subject) {
156
+ return `subject:${JSON.stringify(subject)}`;
157
+ }
158
+ return "unknown";
159
+ }
160
+ function formatTargetSelectorFromParams(params, options = {}) {
161
+ const id = readTrimmedOptionalStringParam(params, "id");
162
+ const subject = readTrimmedOptionalStringParam(params, "subject");
163
+ const last = options.allowLast ? readBooleanParam(params, "last") : void 0;
164
+ const maxValueChars = options.maxValueChars;
165
+ return formatTargetSelector(
166
+ id && maxValueChars !== void 0 ? truncate(id, maxValueChars) : id,
167
+ subject && maxValueChars !== void 0 ? truncate(subject, maxValueChars) : subject,
168
+ last
169
+ );
170
+ }
171
+ function readTrimmedOptionalStringParam(params, key) {
172
+ const value = params[key];
173
+ if (value === void 0 || value === null) {
174
+ return void 0;
175
+ }
176
+ if (typeof value !== "string") {
177
+ throw new Error(`${key} must be a string.`);
178
+ }
179
+ const normalized = value.trim();
180
+ return normalized.length > 0 ? normalized : void 0;
181
+ }
182
+ function sanitizeUpdateToolParams(params) {
183
+ return {
184
+ ...params.id ? { id: params.id } : {},
185
+ ...params.subject ? { subject: params.subject } : {},
186
+ ...params.importance !== void 0 ? { importance: params.importance } : {},
187
+ ...params.expiry !== void 0 ? { expiry: params.expiry } : {},
188
+ ...params.claimKey !== void 0 ? { hasClaimKey: true } : {},
189
+ ...params.validFrom !== void 0 ? { hasValidFrom: true } : {},
190
+ ...params.validTo !== void 0 ? { hasValidTo: true } : {}
191
+ };
192
+ }
193
+ function sanitizeFetchToolParams(params) {
194
+ return {
195
+ ...params.id ? { id: params.id } : {},
196
+ ...params.subject ? { subject: params.subject } : {}
197
+ };
198
+ }
199
+
39
200
  // src/app/episode-ingest/activity-threshold.ts
40
201
  function resolveEpisodeActivityEligibility(materialTurns, startedAt, endedAt, threshold) {
41
202
  const durationMs = resolveTranscriptDurationMs(startedAt, endedAt);
@@ -1172,8 +1333,8 @@ function detectClaimKeyEntityFamilyCandidates(entries) {
1172
1333
  return support?.autoSafe === true;
1173
1334
  });
1174
1335
  const componentProfiles = component.map((entity) => profiles.get(entity)).filter((profile) => Boolean(profile));
1175
- const entryIds = normalizeStringArray(componentProfiles.flatMap((profile) => [...profile.entryIds]));
1176
- const claimKeys = normalizeStringArray(componentProfiles.flatMap((profile) => [...profile.claimKeys]));
1336
+ const entryIds = normalizeStringArray2(componentProfiles.flatMap((profile) => [...profile.entryIds]));
1337
+ const claimKeys = normalizeStringArray2(componentProfiles.flatMap((profile) => [...profile.claimKeys]));
1177
1338
  const confidence = componentSupport.length > 0 ? Math.max(...componentSupport.map((support) => support.confidence)) : 0.75;
1178
1339
  families.push({
1179
1340
  entityPrefixes: [...component].sort((left, right) => left.localeCompare(right)),
@@ -1372,7 +1533,7 @@ function buildPairSupport(profiles) {
1372
1533
  }
1373
1534
  }
1374
1535
  for (const entities of attributeBuckets.values()) {
1375
- const normalizedEntities = normalizeStringArray(entities);
1536
+ const normalizedEntities = normalizeStringArray2(entities);
1376
1537
  if (normalizedEntities.length < 2 || normalizedEntities.length > MAX_ATTRIBUTE_BUCKET_SIZE) {
1377
1538
  continue;
1378
1539
  }
@@ -1463,7 +1624,7 @@ function evaluateEntityFamilyPairSupport(leftProfile, rightProfile) {
1463
1624
  );
1464
1625
  return {
1465
1626
  entityPrefixes: [leftProfile.entityPrefix, rightProfile.entityPrefix],
1466
- supportingEntryIds: normalizeStringArray([...leftProfile.entryIds, ...rightProfile.entryIds]),
1627
+ supportingEntryIds: normalizeStringArray2([...leftProfile.entryIds, ...rightProfile.entryIds]),
1467
1628
  sharedAttributes,
1468
1629
  confidence,
1469
1630
  autoSafe: lexicalRelation.autoSafe && (sharedAttributes.length >= 2 || sharedAttributes.length === 1 && groundingAnchorCount >= 1 && groundingScore >= 2),
@@ -1569,7 +1730,7 @@ function selectCanonicalEntityPrefix(entityPrefixes, pairSupport, profiles) {
1569
1730
  reasons.push(`lexical alias evidence prefers "${entityPrefix}"`);
1570
1731
  }
1571
1732
  scoreByEntity.set(entityPrefix, score);
1572
- reasonsByEntity.set(entityPrefix, normalizeStringArray(reasons));
1733
+ reasonsByEntity.set(entityPrefix, normalizeStringArray2(reasons));
1573
1734
  }
1574
1735
  const ranked = [...scoreByEntity.entries()].sort((left, right) => right[1] - left[1] || left[0].localeCompare(right[0]));
1575
1736
  const [bestCandidate, secondCandidate] = ranked;
@@ -1813,7 +1974,7 @@ function intersectSets(left, right) {
1813
1974
  }
1814
1975
  return intersection.sort((first, second) => first.localeCompare(second));
1815
1976
  }
1816
- function normalizeStringArray(values) {
1977
+ function normalizeStringArray2(values) {
1817
1978
  return Array.from(new Set(values.map((value) => value.trim()).filter((value) => value.length > 0)));
1818
1979
  }
1819
1980
  function buildPairKey(leftEntityPrefix, rightEntityPrefix) {
@@ -2078,7 +2239,7 @@ function evaluateClaimKeySupport(entry, targetClaimKey, trustedHints) {
2078
2239
  familyReuseCount: familyReuseEntries.length,
2079
2240
  groundedFamilyReuseCount: groundedFamilyReuseEntries.length,
2080
2241
  relaxedStableSlotFamilyGate: promotionSupport.relaxedStableSlotFamilyGate,
2081
- supportingEntryIds: normalizeStringArray2([
2242
+ supportingEntryIds: normalizeStringArray3([
2082
2243
  ...groundedExactReuseEntries.map((candidate) => candidate.id),
2083
2244
  ...groundedFamilyReuseEntries.map((candidate) => candidate.id),
2084
2245
  ...familyReuseEntries.filter((candidate) => candidate.id.startsWith("example:")).map((candidate) => candidate.id)
@@ -2134,18 +2295,18 @@ function evaluateClaimKeyCompactness(claimKey, prior) {
2134
2295
  };
2135
2296
  }
2136
2297
  function normalizeGroundingTags(tags) {
2137
- return normalizeStringArray2((tags ?? []).map((tag) => normalizeClaimKeySegment(tag)).filter((tag) => tag.length > 0));
2298
+ return normalizeStringArray3((tags ?? []).map((tag) => normalizeClaimKeySegment(tag)).filter((tag) => tag.length > 0));
2138
2299
  }
2139
2300
  function tokenizeGroundingText(value) {
2140
2301
  if (!value) {
2141
2302
  return [];
2142
2303
  }
2143
- return normalizeStringArray2(
2304
+ return normalizeStringArray3(
2144
2305
  value.split(/[^a-zA-Z0-9]+/u).map((token) => normalizeClaimKeySegment(token)).filter((token) => token.length > 2 && !GROUNDING_STOP_TOKENS.has(token))
2145
2306
  );
2146
2307
  }
2147
2308
  function buildEntryLocalLexicalTokens(entry) {
2148
- return normalizeStringArray2([
2309
+ return normalizeStringArray3([
2149
2310
  ...tokenizeGroundingText(entry.subject),
2150
2311
  ...tokenizeGroundingText(entry.content),
2151
2312
  ...tokenizeGroundingText(entry.source_context),
@@ -2253,7 +2414,7 @@ function intersects(left, right) {
2253
2414
  }
2254
2415
  return false;
2255
2416
  }
2256
- function normalizeStringArray2(values) {
2417
+ function normalizeStringArray3(values) {
2257
2418
  const seen = /* @__PURE__ */ new Set();
2258
2419
  const normalized = [];
2259
2420
  for (const value of values) {
@@ -3891,6 +4052,24 @@ export {
3891
4052
  computeNormContentHash,
3892
4053
  validateEntriesWithIndexes,
3893
4054
  storeEntriesDetailed,
4055
+ formatErrorMessage,
4056
+ buildEntryMemoryResolverPorts,
4057
+ resolveTargetEntry,
4058
+ readBooleanParam,
4059
+ ENTRY_TYPE_DESCRIPTION,
4060
+ EXPIRY_DESCRIPTION,
4061
+ UPDATE_EXPIRY_DESCRIPTION,
4062
+ RECALL_MODES,
4063
+ asRecord,
4064
+ parseExpiry,
4065
+ parseEntryTypes,
4066
+ parseEntryType,
4067
+ parseRecallMode,
4068
+ normalizeStringArray,
4069
+ formatTargetSelector,
4070
+ formatTargetSelectorFromParams,
4071
+ sanitizeUpdateToolParams,
4072
+ sanitizeFetchToolParams,
3894
4073
  backfillEpisodeEmbeddings,
3895
4074
  prepareEpisodeIngest,
3896
4075
  ingestEpisodeTranscript,
@@ -1,7 +1,8 @@
1
1
  import {
2
2
  projectClaimCentricRecallEntry,
3
- runProcedureRecall
4
- } from "./chunk-ELR2HSVC.js";
3
+ runProcedureRecall,
4
+ truncate
5
+ } from "./chunk-FMQTRTWE.js";
5
6
  import {
6
7
  recall
7
8
  } from "./chunk-5LADPJ4C.js";
@@ -355,7 +356,7 @@ function buildCurrentTurnOnlyQuery(currentTurnText, maxChars) {
355
356
  if (maxChars <= 0) {
356
357
  return void 0;
357
358
  }
358
- const query = truncate(normalizeWhitespace(currentTurnText), maxChars);
359
+ const query = truncate2(normalizeWhitespace(currentTurnText), maxChars);
359
360
  return query.length > 0 ? query : void 0;
360
361
  }
361
362
  function buildContextualAnchorQuery(currentTurnQuery, recentTurns, maxChars) {
@@ -369,7 +370,7 @@ function buildContextualAnchorQuery(currentTurnQuery, recentTurns, maxChars) {
369
370
  if (remaining <= 0) {
370
371
  return void 0;
371
372
  }
372
- return `${currentTurnQuery}${separator}${prefix}${truncate(anchor, remaining)}`;
373
+ return `${currentTurnQuery}${separator}${prefix}${truncate2(anchor, remaining)}`;
373
374
  }
374
375
  function buildCompactContextAnchor(recentTurns) {
375
376
  const recentTurn = recentTurns[recentTurns.length - 1];
@@ -377,7 +378,7 @@ function buildCompactContextAnchor(recentTurns) {
377
378
  return void 0;
378
379
  }
379
380
  const normalized = normalizeWhitespace(recentTurn.text);
380
- return normalized.length > 0 ? truncate(normalized, MAX_CONTEXT_ANCHOR_CHARS) : void 0;
381
+ return normalized.length > 0 ? truncate2(normalized, MAX_CONTEXT_ANCHOR_CHARS) : void 0;
381
382
  }
382
383
  function requiresContextualQuery(currentTurnText) {
383
384
  const normalizedTurn = normalizeWhitespace(currentTurnText);
@@ -401,10 +402,10 @@ function shouldAllowContextualFallback(currentTurnText, recentTurns) {
401
402
  function buildProcedureQuery(currentTurnText, recentTurns, maxChars) {
402
403
  const normalizedCurrentTurn = normalizeWhitespace(currentTurnText);
403
404
  if (normalizedCurrentTurn.length > 0) {
404
- return truncate(normalizedCurrentTurn, maxChars);
405
+ return truncate2(normalizedCurrentTurn, maxChars);
405
406
  }
406
407
  const recentUserTurn = [...recentTurns].reverse().find((turn) => turn.role === "user");
407
- return recentUserTurn ? truncate(normalizeWhitespace(recentUserTurn.text), maxChars) : void 0;
408
+ return recentUserTurn ? truncate2(normalizeWhitespace(recentUserTurn.text), maxChars) : void 0;
408
409
  }
409
410
  function applyDirectnessSelection(currentTurnText, items) {
410
411
  if (items.length === 0) {
@@ -748,7 +749,7 @@ function normalizeOptionalString(value) {
748
749
  function normalizeWhitespace(value) {
749
750
  return value.replace(/\s+/g, " ").trim();
750
751
  }
751
- function truncate(value, maxChars) {
752
+ function truncate2(value, maxChars) {
752
753
  if (maxChars <= 0) {
753
754
  return "";
754
755
  }
@@ -764,166 +765,6 @@ function formatErrorMessage(error) {
764
765
  return String(error);
765
766
  }
766
767
 
767
- // src/adapters/shared/memory-tool-format.ts
768
- var DEFAULT_RECALL_LIMIT = 10;
769
- var RESULT_SUBJECT_LOG_LIMIT = 5;
770
- function truncate2(value, maxChars) {
771
- if (value.length <= maxChars) {
772
- return value;
773
- }
774
- return `${value.slice(0, maxChars - 3).trimEnd()}...`;
775
- }
776
- function sanitizeStoreToolParams(params) {
777
- return {
778
- type: params.type,
779
- subject: params.subject,
780
- ...params.importance !== void 0 ? { importance: params.importance } : {},
781
- ...params.expiry !== void 0 ? { expiry: params.expiry } : {},
782
- ...params.tags.length > 0 ? { tags: params.tags } : {},
783
- contentLength: params.content.length,
784
- ...params.sourceContext !== void 0 ? { sourceContextLength: params.sourceContext.length } : {},
785
- ...params.supersedes !== void 0 ? { hasSupersedes: true } : {},
786
- ...params.claimKey !== void 0 ? { hasClaimKey: true } : {},
787
- ...params.validFrom !== void 0 ? { hasValidFrom: true } : {},
788
- ...params.validTo !== void 0 ? { hasValidTo: true } : {}
789
- };
790
- }
791
- function formatRecallToolSummary(params) {
792
- const parts = [`query=${JSON.stringify(truncate2(params.query, 80))}`];
793
- if (params.mode) {
794
- parts.push(`mode=${params.mode}`);
795
- }
796
- if (params.limit !== void 0 && params.limit !== DEFAULT_RECALL_LIMIT) {
797
- parts.push(`limit=${params.limit}`);
798
- }
799
- if (params.types.length > 0) {
800
- parts.push(`types=${JSON.stringify(params.types)}`);
801
- }
802
- if (params.tags.length > 0) {
803
- parts.push(`tags=${JSON.stringify(params.tags)}`);
804
- }
805
- if (params.asOf) {
806
- parts.push(`as_of=${JSON.stringify(params.asOf)}`);
807
- }
808
- return parts.join(" ");
809
- }
810
- function sanitizeRecallToolParams(params) {
811
- return {
812
- query: params.query,
813
- ...params.mode ? { mode: params.mode } : {},
814
- ...params.limit !== void 0 ? { limit: params.limit } : {},
815
- ...params.threshold !== void 0 ? { threshold: params.threshold } : {},
816
- ...params.types.length > 0 ? { types: params.types } : {},
817
- ...params.tags.length > 0 ? { tags: params.tags } : {},
818
- ...params.asOf ? { asOf: params.asOf } : {}
819
- };
820
- }
821
- function formatUnifiedRecallLogSummary(result) {
822
- const procedureCount = result.procedureCandidates.length;
823
- const procedureSummary = result.procedure ? ` [procedure: ${JSON.stringify(truncate2(result.procedure.title, 80))}]` : "";
824
- const entrySubjects = result.entries.map((entry) => entry.entry.subject.trim()).filter((subject) => subject.length > 0);
825
- const displayed = entrySubjects.slice(0, RESULT_SUBJECT_LOG_LIMIT).map((subject) => JSON.stringify(truncate2(subject, 80)));
826
- const remaining = entrySubjects.length - RESULT_SUBJECT_LOG_LIMIT;
827
- const suffix = displayed.length === 0 ? "" : ` [entry subjects: ${displayed.join(", ")}${remaining > 0 ? `, ... and ${remaining} more` : ""}]`;
828
- const entryEpisodeSummary = `${result.episodes.length} episode${result.episodes.length === 1 ? "" : "s"}, ${result.entries.length} entr${result.entries.length === 1 ? "y" : "ies"}`;
829
- if (procedureCount === 0 && !result.procedure) {
830
- return `${entryEpisodeSummary}${suffix}`;
831
- }
832
- return `${procedureCount} procedure candidate${procedureCount === 1 ? "" : "s"}, ${entryEpisodeSummary}${procedureSummary}${suffix}`;
833
- }
834
- function buildRecallToolDetails(result, extraDetails = {}) {
835
- return {
836
- status: "ok",
837
- count: result.count,
838
- ...extraDetails,
839
- routing: {
840
- requested: result.routing.requested,
841
- detectedIntent: result.routing.detectedIntent,
842
- queried: result.routing.queried,
843
- reason: result.routing.reason
844
- },
845
- ...result.asOf ? { asOf: result.asOf } : {},
846
- ...result.timeWindow ? { timeWindow: result.timeWindow } : {},
847
- ...result.procedure ? {
848
- procedure: {
849
- id: result.procedure.id,
850
- procedureKey: result.procedure.procedure_key,
851
- title: result.procedure.title,
852
- goal: result.procedure.goal
853
- }
854
- } : {},
855
- procedures: result.procedureCandidates.map((candidate) => ({
856
- id: candidate.procedure.id,
857
- procedureKey: candidate.procedure.procedure_key,
858
- title: candidate.procedure.title,
859
- goal: candidate.procedure.goal,
860
- score: candidate.score,
861
- lexicalScore: candidate.scores.lexical,
862
- vectorScore: candidate.scores.vector
863
- })),
864
- procedureNotices: result.procedureNotices,
865
- episodes: result.episodes.map((episode) => ({
866
- id: episode.episode.id,
867
- source: episode.episode.source,
868
- sourceId: episode.episode.sourceId,
869
- startedAt: episode.episode.startedAt,
870
- endedAt: episode.episode.endedAt,
871
- tags: episode.episode.tags,
872
- score: episode.score,
873
- activityLevel: episode.episode.activityLevel,
874
- summary: episode.episode.summary,
875
- whyMatched: describeEpisodeWhyMatched(episode.scores.semantic, episode.scores.temporal)
876
- })),
877
- entries: result.entries.map((entry) => ({
878
- id: entry.entry.id,
879
- subject: entry.entry.subject,
880
- type: entry.entry.type,
881
- expiry: entry.entry.expiry,
882
- importance: entry.entry.importance,
883
- score: entry.score,
884
- tags: entry.entry.tags,
885
- content: entry.entry.content
886
- })),
887
- projectedEntries: result.projectedEntries.map((entry) => ({
888
- id: entry.entryId,
889
- familyKey: entry.familyKey,
890
- claimKey: entry.claimKey,
891
- slotPolicy: entry.slotPolicy,
892
- memoryState: entry.memoryState,
893
- claimStatus: entry.claimStatus,
894
- freshness: entry.freshness,
895
- provenance: entry.provenance,
896
- whySurfaced: entry.whySurfaced
897
- })),
898
- entryFamilies: result.entryFamilies.map((family) => ({
899
- familyKey: family.familyKey,
900
- claimKey: family.claimKey,
901
- slotPolicy: family.slotPolicy,
902
- subject: family.subject,
903
- primaryEntryId: family.primary.entryId,
904
- entries: family.entries.map((entry) => ({
905
- id: entry.entryId,
906
- memoryState: entry.memoryState,
907
- claimStatus: entry.claimStatus
908
- }))
909
- })),
910
- claimTransitions: result.claimTransitions,
911
- notices: result.notices
912
- };
913
- }
914
- function describeEpisodeWhyMatched(semanticScore, temporalScore) {
915
- if (semanticScore > 0 && temporalScore > 0) {
916
- return "Semantic match within the resolved time window.";
917
- }
918
- if (semanticScore > 0) {
919
- return "Semantic match to the episode summary.";
920
- }
921
- if (temporalScore > 0) {
922
- return "Session overlaps the resolved time window.";
923
- }
924
- return "Matched episodic recall ranking.";
925
- }
926
-
927
768
  // src/adapters/shared/injection/entry-lines.ts
928
769
  var MAX_CONTENT_CHARS = 220;
929
770
  function formatInjectionEntryHeader(item) {
@@ -938,12 +779,12 @@ function formatInjectionEntryHeader(item) {
938
779
  return `- [${metadata.join(" | ")}] ${item.entry.subject}`;
939
780
  }
940
781
  function formatInjectionEntryBodyLines(item) {
941
- const lines = [` ${truncate2(item.entry.content.trim(), MAX_CONTENT_CHARS)}`];
782
+ const lines = [` ${truncate(item.entry.content.trim(), MAX_CONTENT_CHARS)}`];
942
783
  lines.push(` why: ${item.whySurfaced.summary}`);
943
784
  const metadata = [
944
785
  item.entry.tags.length > 0 ? `tags: ${item.entry.tags.join(", ")}` : void 0,
945
786
  item.freshnessLabel ? `freshness: ${item.freshnessLabel}` : void 0,
946
- item.provenanceSummary ? `provenance: ${truncate2(item.provenanceSummary, MAX_CONTENT_CHARS)}` : void 0
787
+ item.provenanceSummary ? `provenance: ${truncate(item.provenanceSummary, MAX_CONTENT_CHARS)}` : void 0
947
788
  ].filter((value) => value !== void 0);
948
789
  if (metadata.length > 0) {
949
790
  lines.push(` ${metadata.join(" | ")}`);
@@ -1011,25 +852,19 @@ function formatProcedureHeader(suggestion) {
1011
852
  return `- [${metadata.join(" | ")}] ${suggestion.procedure.title}`;
1012
853
  }
1013
854
  function formatProcedureBodyLines(suggestion) {
1014
- const lines = [` goal: ${truncate2(suggestion.procedure.goal.trim(), MAX_CONTENT_CHARS2)}`];
855
+ const lines = [` goal: ${truncate(suggestion.procedure.goal.trim(), MAX_CONTENT_CHARS2)}`];
1015
856
  lines.push(` why: ${suggestion.whySurfaced.summary}`);
1016
857
  if (suggestion.procedure.when_to_use.length > 0) {
1017
- lines.push(` when to use: ${truncate2(suggestion.procedure.when_to_use.join("; "), MAX_CONTENT_CHARS2)}`);
858
+ lines.push(` when to use: ${truncate(suggestion.procedure.when_to_use.join("; "), MAX_CONTENT_CHARS2)}`);
1018
859
  }
1019
860
  if (suggestion.procedure.verification.length > 0) {
1020
- lines.push(` verification: ${truncate2(suggestion.procedure.verification.join("; "), MAX_CONTENT_CHARS2)}`);
861
+ lines.push(` verification: ${truncate(suggestion.procedure.verification.join("; "), MAX_CONTENT_CHARS2)}`);
1021
862
  }
1022
863
  return lines;
1023
864
  }
1024
865
 
1025
866
  export {
1026
867
  runBeforeTurn,
1027
- truncate2 as truncate,
1028
- sanitizeStoreToolParams,
1029
- formatRecallToolSummary,
1030
- sanitizeRecallToolParams,
1031
- formatUnifiedRecallLogSummary,
1032
- buildRecallToolDetails,
1033
868
  formatInjectionEntryHeader,
1034
869
  formatInjectionEntryBodyLines,
1035
870
  wrapAgenrMemoryContext,
@@ -1,3 +1,7 @@
1
+ import {
2
+ formatTargetSelectorFromParams
3
+ } from "./chunk-TMDNFBBC.js";
4
+
1
5
  // src/adapters/openclaw/transcript/parser.ts
2
6
  import { createHash } from "crypto";
3
7
  import * as fs2 from "fs/promises";
@@ -75,6 +79,7 @@ function parseJsonlLines(raw, onRecord) {
75
79
  }
76
80
 
77
81
  // src/adapters/openclaw/transcript/tool-summarization.ts
82
+ var AGENR_FETCH_TARGET_MAX_CHARS = 80;
78
83
  var DEFAULT_TOOL_RESULT_DROP_NAMES = ["read", "web_fetch", "browser", "screenshot", "snapshot", "canvas", "tts"];
79
84
  var DEFAULT_TOOL_RESULT_KEEP_NAMES = ["web_search", "memory_search", "memory_get", "image"];
80
85
  var DEFAULT_TOOL_RESULT_DROP_NAME_SET = new Set(DEFAULT_TOOL_RESULT_DROP_NAMES);
@@ -147,6 +152,9 @@ function toolIdentifier(toolName, args) {
147
152
  const query = getString(args.query) ?? "(no query)";
148
153
  return `"${truncateInline(query, 80)}"`;
149
154
  }
155
+ if (normalizedToolName === "agenr_fetch") {
156
+ return formatTargetSelectorFromParams(args, { maxValueChars: AGENR_FETCH_TARGET_MAX_CHARS });
157
+ }
150
158
  if (normalizedToolName === "message") {
151
159
  const action = getString(args.action) ?? "(unknown action)";
152
160
  const target = getString(args.target) ?? getString(args.to) ?? "(unknown target)";
@@ -247,6 +255,9 @@ function summarizeToolCall(call, options) {
247
255
  const query = getString(args.query) ?? "(no query)";
248
256
  return `[recalled from brain: "${truncateInline(query, 100)}"]`;
249
257
  }
258
+ if (normalizedToolName === "agenr_fetch") {
259
+ return `[fetched from brain: ${formatTargetSelectorFromParams(args, { maxValueChars: AGENR_FETCH_TARGET_MAX_CHARS })}]`;
260
+ }
250
261
  if (normalizedToolName === "sessions_spawn") {
251
262
  const label = getString(args.label);
252
263
  const mode = getString(args.mode) ?? "run";
@@ -550,7 +561,7 @@ async function applyMessageTimestampFallbacks(filePath, messages, options) {
550
561
  // src/adapters/openclaw/transcript/parser.ts
551
562
  var SKIPPED_RECORD_TYPES = /* @__PURE__ */ new Set(["compaction", "custom", "thinking_level_change"]);
552
563
  var TOOL_RESULT_POLICY = {
553
- dropToolNames: /* @__PURE__ */ new Set([...DEFAULT_TOOL_RESULT_DROP_NAMES, "agenr_recall", "image"]),
564
+ dropToolNames: /* @__PURE__ */ new Set([...DEFAULT_TOOL_RESULT_DROP_NAMES, "agenr_recall", "agenr_fetch", "image"]),
554
565
  keepToolNames: new Set(DEFAULT_TOOL_RESULT_KEEP_NAMES.filter((name) => name !== "image"))
555
566
  };
556
567
  var RAW_TEXT_BLOCK_TYPES = /* @__PURE__ */ new Set(["input_text", "output_text", "text"]);