@ethosagent/core 0.3.9 → 0.3.11
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 +19 -3
- package/dist/index.js +116 -19
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
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
|
-
|
|
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
|
-
${
|
|
253
|
+
${escaped}
|
|
253
254
|
</untrusted>`;
|
|
254
255
|
return { content: wrapped, strippedTokens: strippedCount };
|
|
255
256
|
}
|
|
257
|
+
function escapeBodyTags(body) {
|
|
258
|
+
return body.replace(/<(\/?untrusted)/g, "<$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(
|
|
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
|
|
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(
|
|
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(
|
|
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(
|
|
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((
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
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((
|
|
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:
|
|
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
|
|
3507
|
+
import { resolve as resolve5, sep as sep2 } from "path";
|
|
3474
3508
|
function assertWithinBase(base, target) {
|
|
3475
|
-
const resolvedBase =
|
|
3476
|
-
const resolvedTarget =
|
|
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
|
-
|
|
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
|
};
|