@ethosagent/core 0.3.9 → 0.3.10

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/index.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import * as _ethosagent_types from '@ethosagent/types';
2
- import { ClarifyStore, PendingClarify, ClarifyResponse, ClarifyAnswerableBy, ClarifySurfaceType, PersonalityObservabilityConfig, SpanKind, EventSeverity, HookRegistry, LLMProvider, ToolRegistry, PersonalityRegistry, MemoryProvider, SessionStore, ContextInjector, Storage, ContextEngineRegistry, RequestDumpStore, SteerSink, Attachment, KeyValueStore, SecretRef, ToolCapabilities, ToolContext, Tool, PersonalityConfig, ContextEngine, ContextEngineCompactInput, ContextEngineCompactOutput, Message, Session, SessionFilter, StoredMessage, SessionUsage, SearchResult, CompressionEvent, MemoryContext, MemorySnapshot, MemoryEntry, SearchOpts, MemoryUpdate, ListOpts, MemoryEntryRef, ToolResult, VoidHooks, ModifyingHooks, ClaimingHooks, ToolDefinitionLite, CompletionOptions, CompletionChunk, LLMProviderRegistry, LLMProviderFactory, MemoryProviderRegistry, MemoryProviderFactory, RequestDumpRecord, ScopedFetch, ScopedFs, ScopedFsEntry, ScopedProcess, SpawnOpts, ProcessResult, ScopedSecretsResolver, ToolFilterOpts } from '@ethosagent/types';
2
+ import { ClarifyStore, PendingClarify, ClarifyResponse, ClarifyAnswerableBy, ClarifySurfaceType, PersonalityObservabilityConfig, SpanKind, EventSeverity, HookRegistry, LLMProvider, ToolRegistry, PersonalityRegistry, MemoryProvider, SessionStore, ContextInjector, Storage, ContextEngineRegistry, RequestDumpStore, SteerSink, Attachment, KeyValueStore, SecretRef, ToolCapabilities, ToolContext, Tool, PersonalityConfig, ContextEngine, ContextEngineCompactInput, ContextEngineCompactOutput, Message, Session, SessionFilter, StoredMessage, SessionUsage, SearchResult, CompressionEvent, MemoryContext, MemorySnapshot, MemoryEntry, SearchOpts, MemoryUpdate, ListOpts, MemoryEntryRef, ToolResult, VoidHooks, ModifyingHooks, ClaimingHooks, ToolDefinitionLite, CompletionOptions, CompletionChunk, LLMProviderRegistry, LLMProviderFactory, MemoryProviderRegistry, MemoryProviderFactory, RequestDumpRecord, ScopedFetch, ScopedFs, ScopedFsEntry, ScopedProcess, SpawnOpts, ProcessResult, ScopedSecretsResolver, ToolResultReducerRegistry, ToolResultReducer, ToolFilterOpts } from '@ethosagent/types';
3
3
  export { MemoryConflictError } from '@ethosagent/types';
4
4
  import * as _ethosagent_safety_watcher from '@ethosagent/safety-watcher';
5
5
  import { InjectionClassifier } from '@ethosagent/safety-injection';
@@ -597,6 +597,8 @@ declare class InMemorySessionStore implements SessionStore {
597
597
  search(query: string, options?: {
598
598
  limit?: number;
599
599
  sessionId?: string;
600
+ since?: Date;
601
+ until?: Date;
600
602
  }): Promise<SearchResult[]>;
601
603
  recordCompression(event: Omit<CompressionEvent, 'id' | 'createdAt'>): Promise<CompressionEvent>;
602
604
  listCompressions(sessionId: string): Promise<CompressionEvent[]>;
@@ -950,10 +952,24 @@ declare class ScopedSecretsImpl implements ScopedSecretsResolver {
950
952
  get(ref: SecretRef): Promise<string>;
951
953
  }
952
954
 
955
+ declare function parseTemporalBound(input: string): Date | undefined;
956
+ declare function toJournalKey(date: Date): string;
957
+ declare function applyTemporalDecay(results: SearchResult[], options?: {
958
+ halfLifeMs?: number;
959
+ now?: Date;
960
+ }): SearchResult[];
961
+
962
+ declare class DefaultToolResultReducerRegistry implements ToolResultReducerRegistry {
963
+ private readonly byName;
964
+ register(reducer: ToolResultReducer): () => void;
965
+ get(toolName: string): ToolResultReducer | undefined;
966
+ }
967
+
953
968
  declare class DefaultToolRegistry implements ToolRegistry {
954
969
  private readonly tools;
955
970
  private readonly backends?;
956
- constructor(backends?: CapabilityBackends);
971
+ private readonly reducers?;
972
+ constructor(backends?: CapabilityBackends, reducers?: ToolResultReducerRegistry);
957
973
  register(tool: Tool, opts?: {
958
974
  pluginId?: string;
959
975
  }): void;
@@ -1020,4 +1036,4 @@ declare class SsrfError extends Error {
1020
1036
  */
1021
1037
  declare function validateUrl(urlStr: string, opts?: ValidateUrlOptions): URL;
1022
1038
 
1023
- export { type AgentEvent, AgentLoop, type AgentLoopConfig, type AgentLoopObservability, BoundaryEscapeError, type CapabilityBackends, type CapabilityScopeIds, type CapabilityValidationError, ChainedProvider, type ChainedProviderOptions, ClarifyBridge, ClarifyBusyError, ClarifyNoSurfaceError, type ClarifyPresenter, type ClarifyRequestInput, type ClarifyResolvedListener, ClarifyTimedOutNoDefaultError, DefaultContextEngineRegistry, type DefaultContextEngineRegistryOptions, DefaultHookRegistry, DefaultLLMProviderRegistry, DefaultMemoryProviderRegistry, DefaultPersonalityRegistry, DefaultToolRegistry, DropOldestEngine, type DryRunToolPlan, EagerPrefetchPolicy, FileClarifyStore, InMemoryRequestDumpStore, InMemorySessionStore, type InMemoryToolContextOptions, KNOWN_AGENT_EVENT_TYPES, type KnownAgentEventType, LastWriteWinsPolicy, LazyOnDemandPolicy, NoopMemoryProvider, type PluginFactory, PluginRegistry, ReferencePreservingEngine, type RunOptions, ScopedFetchImpl, ScopedFsImpl, ScopedProcessImpl, ScopedSecretsImpl, type SecretsBackend, SemanticSummaryEngine, SsrfError, type SummarizerFn, type ValidateUrlOptions, assertWithinBase, buildAttachmentAnnotation, deriveBotKey, estimateMessageTokens, estimateMessagesTokens, estimateTokens, isKnownAgentEvent, makeTestToolContext, redactArgs, resolveCapabilities, stripAnsiEscapes, synthesizeDryRunCapResult, synthesizeDryRunResult, validateRegistration, validateUrl };
1039
+ export { type AgentEvent, AgentLoop, type AgentLoopConfig, type AgentLoopObservability, BoundaryEscapeError, type CapabilityBackends, type CapabilityScopeIds, type CapabilityValidationError, ChainedProvider, type ChainedProviderOptions, ClarifyBridge, ClarifyBusyError, ClarifyNoSurfaceError, type ClarifyPresenter, type ClarifyRequestInput, type ClarifyResolvedListener, ClarifyTimedOutNoDefaultError, DefaultContextEngineRegistry, type DefaultContextEngineRegistryOptions, DefaultHookRegistry, DefaultLLMProviderRegistry, DefaultMemoryProviderRegistry, DefaultPersonalityRegistry, DefaultToolRegistry, DefaultToolResultReducerRegistry, DropOldestEngine, type DryRunToolPlan, EagerPrefetchPolicy, FileClarifyStore, InMemoryRequestDumpStore, InMemorySessionStore, type InMemoryToolContextOptions, KNOWN_AGENT_EVENT_TYPES, type KnownAgentEventType, LastWriteWinsPolicy, LazyOnDemandPolicy, NoopMemoryProvider, type PluginFactory, PluginRegistry, ReferencePreservingEngine, type RunOptions, ScopedFetchImpl, ScopedFsImpl, ScopedProcessImpl, ScopedSecretsImpl, type SecretsBackend, SemanticSummaryEngine, SsrfError, type SummarizerFn, type ValidateUrlOptions, applyTemporalDecay, assertWithinBase, buildAttachmentAnnotation, deriveBotKey, estimateMessageTokens, estimateMessagesTokens, estimateTokens, isKnownAgentEvent, makeTestToolContext, parseTemporalBound, redactArgs, resolveCapabilities, stripAnsiEscapes, synthesizeDryRunCapResult, synthesizeDryRunResult, toJournalKey, validateRegistration, validateUrl };
package/dist/index.js CHANGED
@@ -248,11 +248,15 @@ function wrapUntrusted({ content, toolName, source }) {
248
248
  const { content: sanitized, strippedCount } = sanitizeTemplateTokens(content);
249
249
  const sourceAttr = encodeAttr(source ?? "unknown");
250
250
  const toolAttr = encodeAttr(toolName);
251
+ const escaped = escapeBodyTags(sanitized);
251
252
  const wrapped = `<untrusted source="${sourceAttr}" tool="${toolAttr}">
252
- ${sanitized}
253
+ ${escaped}
253
254
  </untrusted>`;
254
255
  return { content: wrapped, strippedTokens: strippedCount };
255
256
  }
257
+ function escapeBodyTags(body) {
258
+ return body.replace(/<(\/?untrusted)/g, "&lt;$1");
259
+ }
256
260
  function encodeAttr(value) {
257
261
  return value.replace(/[\r\n]+/g, " ").replace(/[<>]/g, "").replace(/"/g, "'").slice(0, 256);
258
262
  }
@@ -275,6 +279,8 @@ function defaultAlwaysDeny() {
275
279
  `${home}/.psql_history`,
276
280
  `${home}/.mysql_history`,
277
281
  `${home}/.npmrc`,
282
+ `${home}/.ethos/keys.json`,
283
+ `${home}/.ethos/secrets`,
278
284
  `${home}/Library/Keychains`,
279
285
  "/etc/passwd",
280
286
  "/etc/shadow",
@@ -283,7 +289,9 @@ function defaultAlwaysDeny() {
283
289
  "/root",
284
290
  "/boot",
285
291
  "/sys",
286
- "/proc/sys"
292
+ "/proc/sys",
293
+ "/proc/self/environ",
294
+ "/proc/self/cmdline"
287
295
  ];
288
296
  }
289
297
 
@@ -342,7 +350,11 @@ import { createHash as createHash2 } from "crypto";
342
350
  // ../storage-fs/src/in-memory-storage.ts
343
351
  import { dirname } from "path";
344
352
 
353
+ // ../storage-fs/src/path-safety.ts
354
+ import { resolve as resolve2 } from "path";
355
+
345
356
  // ../storage-fs/src/scoped-storage.ts
357
+ import { resolve as resolve3 } from "path";
346
358
  import {
347
359
  BoundaryError
348
360
  } from "@ethosagent/types";
@@ -357,7 +369,8 @@ var ScopedStorage = class {
357
369
  readPrefixes;
358
370
  writePrefixes;
359
371
  denyPrefixes;
360
- check(path, kind) {
372
+ check(rawPath, kind) {
373
+ const path = resolve3(rawPath);
361
374
  if (isPathAllowed(path, this.denyPrefixes)) {
362
375
  throw new BoundaryError(kind, path, this.denyPrefixes, "always-deny floor");
363
376
  }
@@ -714,6 +727,8 @@ var InMemorySessionStore = class {
714
727
  for (const [sessionId, msgs] of this.messages.entries()) {
715
728
  if (options?.sessionId && sessionId !== options.sessionId) continue;
716
729
  for (const msg of msgs) {
730
+ if (options?.since && msg.timestamp < options.since) continue;
731
+ if (options?.until && msg.timestamp > options.until) continue;
717
732
  const idx = msg.content.toLowerCase().indexOf(lower);
718
733
  if (idx >= 0) {
719
734
  results.push({
@@ -828,8 +843,8 @@ init_dry_run();
828
843
 
829
844
  // src/hook-registry.ts
830
845
  function isAllowed(h, allowedPlugins) {
831
- if (allowedPlugins === void 0) return true;
832
846
  if (!h.pluginId) return true;
847
+ if (allowedPlugins === void 0) return false;
833
848
  return allowedPlugins.includes(h.pluginId);
834
849
  }
835
850
  var DefaultHookRegistry = class {
@@ -949,6 +964,12 @@ var ScopedAttachmentsImpl = class {
949
964
  if (!this.attachments.some((a) => a.ref === att.ref)) {
950
965
  throw new Error(`Attachment ref "${att.ref}" is not in the scoped list for this tool`);
951
966
  }
967
+ const scoped = this.attachments.find((a) => a.ref === att.ref);
968
+ if (scoped && scoped.url !== att.url) {
969
+ throw new Error(
970
+ `Attachment URL mismatch: caller supplied "${att.url}" but scoped list has "${scoped.url}"`
971
+ );
972
+ }
952
973
  if (att.url.startsWith("file://")) {
953
974
  return { path: this.cache.resolveLocalPath(att.url) };
954
975
  }
@@ -984,7 +1005,7 @@ var CLOUD_METADATA_HOSTS = /* @__PURE__ */ new Set([
984
1005
  "169.254.0.23"
985
1006
  ]);
986
1007
  function isCloudMetadataHost(hostname) {
987
- const normalized = hostname.toLowerCase().replace(/^\[|\]$/g, "");
1008
+ const normalized = hostname.toLowerCase().replace(/^\[|\]$/g, "").replace(/\.$/, "");
988
1009
  return CLOUD_METADATA_HOSTS.has(normalized);
989
1010
  }
990
1011
 
@@ -1161,6 +1182,8 @@ function isPrivateIpv6(ip) {
1161
1182
  const d = low & 255;
1162
1183
  return isPrivateIpv4(`${a}.${b}.${c}.${d}`);
1163
1184
  }
1185
+ const compat = lower.match(/^::(\d+\.\d+\.\d+\.\d+)$/);
1186
+ if (compat) return isPrivateIpv4(compat[1]);
1164
1187
  return false;
1165
1188
  }
1166
1189
  function isPrivateIp(ip) {
@@ -1269,13 +1292,13 @@ var ScopedFetchImpl = class {
1269
1292
  };
1270
1293
 
1271
1294
  // src/scoped/scoped-fs.ts
1272
- import { normalize, resolve as resolve2 } from "path";
1295
+ import { normalize, resolve as resolve4 } from "path";
1273
1296
  var ScopedFsImpl = class {
1274
1297
  constructor(storage, readPaths, writePaths) {
1275
1298
  this.storage = storage;
1276
1299
  this.readPaths = readPaths;
1277
1300
  this.writePaths = writePaths;
1278
- this.denyPaths = defaultAlwaysDeny().map((p) => normalize(resolve2(p)));
1301
+ this.denyPaths = defaultAlwaysDeny().map((p) => normalize(resolve4(p)));
1279
1302
  }
1280
1303
  storage;
1281
1304
  readPaths;
@@ -1318,14 +1341,14 @@ var ScopedFsImpl = class {
1318
1341
  return this.storage.listEntries(dir);
1319
1342
  }
1320
1343
  checkReach(path, allowed, kind) {
1321
- const canonical = normalize(resolve2(path));
1344
+ const canonical = normalize(resolve4(path));
1322
1345
  for (const deny of this.denyPaths) {
1323
1346
  if (canonical === deny || canonical.startsWith(deny.endsWith("/") ? deny : `${deny}/`)) {
1324
1347
  throw new Error(`PATH_NOT_REACHABLE: ${kind} of "${path}" hits the always-deny floor`);
1325
1348
  }
1326
1349
  }
1327
1350
  for (const prefix of allowed) {
1328
- const canonicalPrefix = normalize(resolve2(prefix));
1351
+ const canonicalPrefix = normalize(resolve4(prefix));
1329
1352
  if (canonical === canonicalPrefix || canonical.startsWith(
1330
1353
  canonicalPrefix.endsWith("/") ? canonicalPrefix : `${canonicalPrefix}/`
1331
1354
  ))
@@ -1346,7 +1369,7 @@ var ScopedProcessImpl = class {
1346
1369
  if (!this.allowedBinaries.has("*") && !this.allowedBinaries.has(binary)) {
1347
1370
  throw new Error(`BINARY_NOT_ALLOWED: ${binary} is not in the declared allowedBinaries`);
1348
1371
  }
1349
- return new Promise((resolve4, reject) => {
1372
+ return new Promise((resolve6, reject) => {
1350
1373
  const child = nodeSpawn(binary, args, {
1351
1374
  cwd: opts?.cwd,
1352
1375
  env: opts?.env ? { ...process.env, ...opts.env } : process.env,
@@ -1359,7 +1382,7 @@ var ScopedProcessImpl = class {
1359
1382
  child.stderr.on("data", (chunk) => stderr.push(chunk));
1360
1383
  child.on("error", reject);
1361
1384
  child.on("close", (exitCode) => {
1362
- resolve4({
1385
+ resolve6({
1363
1386
  exitCode: exitCode ?? 1,
1364
1387
  stdout: Buffer.concat(stdout).toString(),
1365
1388
  stderr: Buffer.concat(stderr).toString()
@@ -1555,11 +1578,20 @@ function passesFilter(entry, filterOpts) {
1555
1578
  }
1556
1579
  return true;
1557
1580
  }
1581
+ function safeReduce(r, result, ctx) {
1582
+ try {
1583
+ return r.reduce(result, ctx);
1584
+ } catch {
1585
+ return result;
1586
+ }
1587
+ }
1558
1588
  var DefaultToolRegistry = class {
1559
1589
  tools = /* @__PURE__ */ new Map();
1560
1590
  backends;
1561
- constructor(backends) {
1591
+ reducers;
1592
+ constructor(backends, reducers) {
1562
1593
  this.backends = backends;
1594
+ this.reducers = reducers;
1563
1595
  }
1564
1596
  register(tool, opts) {
1565
1597
  this.tools.set(tool.name, { tool, pluginId: opts?.pluginId });
@@ -1731,7 +1763,9 @@ var DefaultToolRegistry = class {
1731
1763
  );
1732
1764
  Object.assign(toolCtx, resolved);
1733
1765
  }
1734
- const result = await entry.tool.execute(call.args, toolCtx);
1766
+ const rawResult = await entry.tool.execute(call.args, toolCtx);
1767
+ const reducer = this.reducers?.get(call.name);
1768
+ const result = reducer ? safeReduce(reducer, rawResult, { args: call.args, turnCount: ctx.currentTurn ?? 0 }) : rawResult;
1735
1769
  if (result.ok && result.value.length > budget) {
1736
1770
  return {
1737
1771
  toolCallId: call.toolCallId,
@@ -3116,11 +3150,11 @@ var ClarifyBridge = class {
3116
3150
  defaultDeadlineAt: deadline.toISOString()
3117
3151
  };
3118
3152
  await this.store.add(row);
3119
- return new Promise((resolve4, reject) => {
3153
+ return new Promise((resolve6, reject) => {
3120
3154
  const timer = setTimeout(() => {
3121
3155
  void this.fireTimeout(requestId);
3122
3156
  }, input.timeoutMs);
3123
- this.pending.set(requestId, { row, resolve: resolve4, reject, timer });
3157
+ this.pending.set(requestId, { row, resolve: resolve6, reject, timer });
3124
3158
  if (input.abortSignal) {
3125
3159
  if (input.abortSignal.aborted) {
3126
3160
  void this.respond({ requestId, answer: "", source: "cancel" });
@@ -3470,10 +3504,10 @@ var LastWriteWinsPolicy = class {
3470
3504
  };
3471
3505
 
3472
3506
  // src/path-boundary.ts
3473
- import { resolve as resolve3, sep as sep2 } from "path";
3507
+ import { resolve as resolve5, sep as sep2 } from "path";
3474
3508
  function assertWithinBase(base, target) {
3475
- const resolvedBase = resolve3(base);
3476
- const resolvedTarget = resolve3(target);
3509
+ const resolvedBase = resolve5(base);
3510
+ const resolvedTarget = resolve5(target);
3477
3511
  if (resolvedTarget === resolvedBase) return;
3478
3512
  if (!resolvedTarget.startsWith(resolvedBase + sep2)) {
3479
3513
  throw new BoundaryEscapeError(resolvedBase, resolvedTarget);
@@ -3696,10 +3730,57 @@ var ANSI_RE = new RegExp(
3696
3730
  `${ESC}\\[[?!>]?[0-9;]*[A-Za-z~]|${ESC}\\][^${BEL}${ESC}]*(?:${BEL}|${ESC}\\\\)|${ESC}\\([A-B0-2]|${ESC}[DME78HNO=>cfn]`,
3697
3731
  "g"
3698
3732
  );
3733
+ var MAX_STRIP_ITERATIONS = 10;
3699
3734
  function stripAnsiEscapes(input) {
3700
- return input.replace(ANSI_RE, "");
3735
+ let result = input;
3736
+ for (let i = 0; i < MAX_STRIP_ITERATIONS; i++) {
3737
+ const next = result.replace(ANSI_RE, "");
3738
+ if (next === result) return next;
3739
+ result = next;
3740
+ }
3741
+ return result;
3742
+ }
3743
+
3744
+ // src/temporal.ts
3745
+ function parseTemporalBound(input) {
3746
+ const d = new Date(input);
3747
+ return Number.isNaN(d.getTime()) ? void 0 : d;
3748
+ }
3749
+ function toJournalKey(date) {
3750
+ const y = date.getUTCFullYear();
3751
+ const m = String(date.getUTCMonth() + 1).padStart(2, "0");
3752
+ const d = String(date.getUTCDate()).padStart(2, "0");
3753
+ return `${y}-${m}-${d}`;
3754
+ }
3755
+ var DEFAULT_HALF_LIFE_MS = 6048e5;
3756
+ function applyTemporalDecay(results, options) {
3757
+ const halfLifeMs = options?.halfLifeMs ?? DEFAULT_HALF_LIFE_MS;
3758
+ const now = options?.now ?? /* @__PURE__ */ new Date();
3759
+ const nowMs = now.getTime();
3760
+ return results.map((r) => {
3761
+ const ageMs = nowMs - r.timestamp.getTime();
3762
+ const decayFactor = ageMs < 0 ? 1 : 0.5 ** (ageMs / halfLifeMs);
3763
+ return { ...r, score: r.score * decayFactor };
3764
+ }).sort((a, b) => b.score - a.score);
3701
3765
  }
3702
3766
 
3767
+ // src/tool-reducer-registry.ts
3768
+ var DefaultToolResultReducerRegistry = class {
3769
+ byName = /* @__PURE__ */ new Map();
3770
+ register(reducer) {
3771
+ if (this.byName.has(reducer.toolName)) {
3772
+ throw new Error(`Reducer already registered for tool '${reducer.toolName}'`);
3773
+ }
3774
+ this.byName.set(reducer.toolName, reducer);
3775
+ return () => {
3776
+ this.byName.delete(reducer.toolName);
3777
+ };
3778
+ }
3779
+ get(toolName) {
3780
+ return this.byName.get(toolName);
3781
+ }
3782
+ };
3783
+
3703
3784
  // src/url-validator.ts
3704
3785
  import { isIP } from "net";
3705
3786
  var IPV4_RE2 = /^(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})$/;
@@ -3733,6 +3814,18 @@ function isPrivateIpv62(ip) {
3733
3814
  if (lower.startsWith("ff")) return true;
3734
3815
  const mapped = lower.match(/^::ffff:(\d+\.\d+\.\d+\.\d+)$/);
3735
3816
  if (mapped) return isPrivateIpv42(mapped[1]);
3817
+ const hexMapped = lower.match(/^::ffff:([0-9a-f]{1,4}):([0-9a-f]{1,4})$/);
3818
+ if (hexMapped) {
3819
+ const high = Number.parseInt(hexMapped[1], 16);
3820
+ const low = Number.parseInt(hexMapped[2], 16);
3821
+ const a = high >> 8 & 255;
3822
+ const b = high & 255;
3823
+ const c = low >> 8 & 255;
3824
+ const d = low & 255;
3825
+ return isPrivateIpv42(`${a}.${b}.${c}.${d}`);
3826
+ }
3827
+ const compat = lower.match(/^::(\d+\.\d+\.\d+\.\d+)$/);
3828
+ if (compat) return isPrivateIpv42(compat[1]);
3736
3829
  return false;
3737
3830
  }
3738
3831
  function isPrivateIp2(ip) {
@@ -3814,6 +3907,7 @@ export {
3814
3907
  DefaultMemoryProviderRegistry,
3815
3908
  DefaultPersonalityRegistry,
3816
3909
  DefaultToolRegistry,
3910
+ DefaultToolResultReducerRegistry,
3817
3911
  DropOldestEngine,
3818
3912
  EagerPrefetchPolicy,
3819
3913
  FileClarifyStore,
@@ -3832,6 +3926,7 @@ export {
3832
3926
  ScopedSecretsImpl,
3833
3927
  SemanticSummaryEngine,
3834
3928
  SsrfError,
3929
+ applyTemporalDecay,
3835
3930
  assertWithinBase,
3836
3931
  buildAttachmentAnnotation,
3837
3932
  deriveBotKey,
@@ -3840,11 +3935,13 @@ export {
3840
3935
  estimateTokens,
3841
3936
  isKnownAgentEvent,
3842
3937
  makeTestToolContext,
3938
+ parseTemporalBound,
3843
3939
  redactArgs,
3844
3940
  resolveCapabilities,
3845
3941
  stripAnsiEscapes,
3846
3942
  synthesizeDryRunCapResult,
3847
3943
  synthesizeDryRunResult,
3944
+ toJournalKey,
3848
3945
  validateRegistration,
3849
3946
  validateUrl2 as validateUrl
3850
3947
  };