@agenticmail/core 0.9.13 → 0.9.15
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.cjs +1921 -7
- package/dist/index.d.cts +497 -1
- package/dist/index.d.ts +497 -1
- package/dist/index.js +1885 -6
- package/package.json +2 -2
package/dist/index.d.cts
CHANGED
|
@@ -1692,6 +1692,293 @@ declare class SmsPoller {
|
|
|
1692
1692
|
private pollOnce;
|
|
1693
1693
|
}
|
|
1694
1694
|
|
|
1695
|
+
declare const ELKS_REALTIME_AUDIO_FORMATS: readonly ["ulaw", "pcm_16000", "pcm_24000", "wav"];
|
|
1696
|
+
type ElksRealtimeAudioFormat = typeof ELKS_REALTIME_AUDIO_FORMATS[number];
|
|
1697
|
+
interface ElksRealtimeHelloMessage {
|
|
1698
|
+
t: 'hello';
|
|
1699
|
+
callid: string;
|
|
1700
|
+
from: string;
|
|
1701
|
+
to: string;
|
|
1702
|
+
[key: string]: unknown;
|
|
1703
|
+
}
|
|
1704
|
+
interface ElksRealtimeAudioMessage {
|
|
1705
|
+
t: 'audio';
|
|
1706
|
+
data: string;
|
|
1707
|
+
}
|
|
1708
|
+
interface ElksRealtimeByeMessage {
|
|
1709
|
+
t: 'bye';
|
|
1710
|
+
reason?: string;
|
|
1711
|
+
message?: string;
|
|
1712
|
+
[key: string]: unknown;
|
|
1713
|
+
}
|
|
1714
|
+
type ElksRealtimeInboundMessage = ElksRealtimeHelloMessage | ElksRealtimeAudioMessage | ElksRealtimeByeMessage;
|
|
1715
|
+
type ElksRealtimeOutboundMessage = {
|
|
1716
|
+
t: 'listening';
|
|
1717
|
+
format: ElksRealtimeAudioFormat;
|
|
1718
|
+
} | {
|
|
1719
|
+
t: 'sending';
|
|
1720
|
+
format: ElksRealtimeAudioFormat;
|
|
1721
|
+
} | {
|
|
1722
|
+
t: 'audio';
|
|
1723
|
+
data: string;
|
|
1724
|
+
} | {
|
|
1725
|
+
t: 'interrupt';
|
|
1726
|
+
} | {
|
|
1727
|
+
t: 'bye';
|
|
1728
|
+
};
|
|
1729
|
+
declare function parseElksRealtimeMessage(input: unknown): ElksRealtimeInboundMessage;
|
|
1730
|
+
declare function buildElksListeningMessage(format?: ElksRealtimeAudioFormat): ElksRealtimeOutboundMessage;
|
|
1731
|
+
declare function buildElksSendingMessage(format?: ElksRealtimeAudioFormat): ElksRealtimeOutboundMessage;
|
|
1732
|
+
declare function buildElksAudioMessage(data: string | Uint8Array): ElksRealtimeOutboundMessage;
|
|
1733
|
+
declare function buildElksInterruptMessage(): ElksRealtimeOutboundMessage;
|
|
1734
|
+
declare function buildElksByeMessage(): ElksRealtimeOutboundMessage;
|
|
1735
|
+
declare function buildElksHandshakeMessages(options?: {
|
|
1736
|
+
listenFormat?: ElksRealtimeAudioFormat;
|
|
1737
|
+
sendFormat?: ElksRealtimeAudioFormat;
|
|
1738
|
+
}): ElksRealtimeOutboundMessage[];
|
|
1739
|
+
|
|
1740
|
+
declare const PHONE_REGION_SCOPES: readonly ["AT", "DE", "EU", "WORLD"];
|
|
1741
|
+
type PhoneRegionScope = typeof PHONE_REGION_SCOPES[number];
|
|
1742
|
+
declare const TELEPHONY_TRANSPORT_CAPABILITIES: readonly ["sms", "call_control", "realtime_media", "recording_supported"];
|
|
1743
|
+
type TelephonyTransportCapability = typeof TELEPHONY_TRANSPORT_CAPABILITIES[number];
|
|
1744
|
+
declare const PHONE_MISSION_STATES: readonly ["draft", "approved", "dialing", "connected", "conversing", "needs_operator", "completed", "failed", "cancelled"];
|
|
1745
|
+
type PhoneMissionState = typeof PHONE_MISSION_STATES[number];
|
|
1746
|
+
type PhoneNumberRisk = 'invalid' | 'standard' | 'premium_or_special';
|
|
1747
|
+
/**
|
|
1748
|
+
* Server-side hard ceilings for a phone mission policy.
|
|
1749
|
+
*
|
|
1750
|
+
* Hardening (#42-H1 / #43-H2) — `policy` is supplied by the calling agent,
|
|
1751
|
+
* so a caller-set `maxCallDurationSeconds: 999999` or `maxCostPerMission:
|
|
1752
|
+
* 1e9` is self-authorized and meaningless as a limit. These constants are
|
|
1753
|
+
* the real ceiling: `validatePhoneMissionPolicy` clamps every caller value
|
|
1754
|
+
* down to (at most) the server cap, so the effective policy can only ever
|
|
1755
|
+
* be MORE restrictive than the server, never less. A phone mission places
|
|
1756
|
+
* real, billed calls — these bounds are the financial blast-radius cap.
|
|
1757
|
+
*/
|
|
1758
|
+
declare const PHONE_SERVER_MAX_CALL_DURATION_SECONDS = 3600;
|
|
1759
|
+
declare const PHONE_SERVER_MAX_COST_PER_MISSION = 5;
|
|
1760
|
+
declare const PHONE_SERVER_MAX_ATTEMPTS = 3;
|
|
1761
|
+
/** Hard cap on the free-text `task` fed to the voice runtime. */
|
|
1762
|
+
declare const PHONE_TASK_MAX_LENGTH = 2000;
|
|
1763
|
+
interface PhoneConfirmPolicy {
|
|
1764
|
+
paymentDetails: 'never';
|
|
1765
|
+
contractCommitment: 'never';
|
|
1766
|
+
costOverLimit: 'needs_operator';
|
|
1767
|
+
sensitivePersonalData: 'needs_operator';
|
|
1768
|
+
unclearAlternative: 'needs_operator';
|
|
1769
|
+
}
|
|
1770
|
+
interface PhoneAlternativePolicy {
|
|
1771
|
+
maxTimeShiftMinutes: number;
|
|
1772
|
+
}
|
|
1773
|
+
interface OpenClawPhoneMissionPolicy {
|
|
1774
|
+
policyVersion: 1;
|
|
1775
|
+
regionAllowlist: PhoneRegionScope[];
|
|
1776
|
+
maxCallDurationSeconds: number;
|
|
1777
|
+
maxCostPerMission: number;
|
|
1778
|
+
maxAttempts: number;
|
|
1779
|
+
transcriptEnabled: boolean;
|
|
1780
|
+
recordingEnabled: boolean;
|
|
1781
|
+
confirmPolicy: PhoneConfirmPolicy;
|
|
1782
|
+
alternativePolicy: PhoneAlternativePolicy;
|
|
1783
|
+
}
|
|
1784
|
+
interface StartPhoneMissionInput {
|
|
1785
|
+
to: string;
|
|
1786
|
+
task: string;
|
|
1787
|
+
policy: OpenClawPhoneMissionPolicy;
|
|
1788
|
+
voiceRuntimeRef?: string;
|
|
1789
|
+
}
|
|
1790
|
+
interface PhoneTransportProfile {
|
|
1791
|
+
provider: string;
|
|
1792
|
+
phoneNumber: string;
|
|
1793
|
+
capabilities: TelephonyTransportCapability[];
|
|
1794
|
+
supportedRegions: PhoneRegionScope[];
|
|
1795
|
+
}
|
|
1796
|
+
interface PhoneMissionValidationIssue {
|
|
1797
|
+
code: string;
|
|
1798
|
+
field: string;
|
|
1799
|
+
message: string;
|
|
1800
|
+
}
|
|
1801
|
+
type PhoneMissionValidationResult = {
|
|
1802
|
+
ok: true;
|
|
1803
|
+
policy: OpenClawPhoneMissionPolicy;
|
|
1804
|
+
issues: [];
|
|
1805
|
+
} | {
|
|
1806
|
+
ok: false;
|
|
1807
|
+
issues: PhoneMissionValidationIssue[];
|
|
1808
|
+
};
|
|
1809
|
+
type PhoneTransportValidationResult = {
|
|
1810
|
+
ok: true;
|
|
1811
|
+
transport: PhoneTransportProfile;
|
|
1812
|
+
issues: [];
|
|
1813
|
+
} | {
|
|
1814
|
+
ok: false;
|
|
1815
|
+
issues: PhoneMissionValidationIssue[];
|
|
1816
|
+
};
|
|
1817
|
+
interface ValidatedPhoneMissionStart {
|
|
1818
|
+
to: string;
|
|
1819
|
+
task: string;
|
|
1820
|
+
policy: OpenClawPhoneMissionPolicy;
|
|
1821
|
+
targetRegion: PhoneRegionScope;
|
|
1822
|
+
transport: PhoneTransportProfile;
|
|
1823
|
+
voiceRuntimeRef?: string;
|
|
1824
|
+
}
|
|
1825
|
+
type PhoneMissionStartValidationResult = {
|
|
1826
|
+
ok: true;
|
|
1827
|
+
mission: ValidatedPhoneMissionStart;
|
|
1828
|
+
issues: [];
|
|
1829
|
+
} | {
|
|
1830
|
+
ok: false;
|
|
1831
|
+
issues: PhoneMissionValidationIssue[];
|
|
1832
|
+
};
|
|
1833
|
+
declare function validatePhoneMissionPolicy(policy: unknown): PhoneMissionValidationResult;
|
|
1834
|
+
declare function validatePhoneTransportProfile(transport: unknown): PhoneTransportValidationResult;
|
|
1835
|
+
declare function inferPhoneRegion(phoneNumber: string): PhoneRegionScope | null;
|
|
1836
|
+
declare function isPhoneRegionAllowed(region: PhoneRegionScope, allowlist: readonly PhoneRegionScope[]): boolean;
|
|
1837
|
+
declare function classifyPhoneNumberRisk(phoneNumber: string): PhoneNumberRisk;
|
|
1838
|
+
declare function validatePhoneMissionStart(input: unknown, transport: unknown, options?: {
|
|
1839
|
+
allowPremiumOrSpecialNumbers?: boolean;
|
|
1840
|
+
}): PhoneMissionStartValidationResult;
|
|
1841
|
+
|
|
1842
|
+
type PhoneTransportProvider = '46elks';
|
|
1843
|
+
/**
|
|
1844
|
+
* Abuse / cost controls for the call-control surface. A phone mission
|
|
1845
|
+
* places a real, billed outbound call, so /calls/start needs hard limits
|
|
1846
|
+
* that the caller cannot raise (see #43-H1).
|
|
1847
|
+
*/
|
|
1848
|
+
declare const PHONE_RATE_LIMIT_PER_MINUTE = 5;
|
|
1849
|
+
declare const PHONE_RATE_LIMIT_PER_HOUR = 30;
|
|
1850
|
+
declare const PHONE_MAX_CONCURRENT_MISSIONS = 3;
|
|
1851
|
+
/** Minimum entropy for an agent-supplied webhook secret (#43-H8). */
|
|
1852
|
+
declare const PHONE_MIN_WEBHOOK_SECRET_LENGTH = 24;
|
|
1853
|
+
/**
|
|
1854
|
+
* Thrown by the webhook handlers for ANY authentication failure —
|
|
1855
|
+
* unknown mission, missing token, or wrong token alike. Uniform on
|
|
1856
|
+
* purpose: the route maps it to a single 403 + generic body so an
|
|
1857
|
+
* unauthenticated caller cannot tell a real missionId from a fake one
|
|
1858
|
+
* (#43-H3 — the 404-vs-403 enumeration oracle).
|
|
1859
|
+
*/
|
|
1860
|
+
declare class PhoneWebhookAuthError extends Error {
|
|
1861
|
+
readonly isPhoneWebhookAuthError = true;
|
|
1862
|
+
constructor();
|
|
1863
|
+
}
|
|
1864
|
+
/** Thrown when /calls/start is refused by a rate/concurrency limit (#43-H1). */
|
|
1865
|
+
declare class PhoneRateLimitError extends Error {
|
|
1866
|
+
readonly isPhoneRateLimitError = true;
|
|
1867
|
+
constructor(message: string);
|
|
1868
|
+
}
|
|
1869
|
+
interface PhoneTransportConfig extends PhoneTransportProfile {
|
|
1870
|
+
provider: PhoneTransportProvider;
|
|
1871
|
+
username: string;
|
|
1872
|
+
password: string;
|
|
1873
|
+
webhookBaseUrl: string;
|
|
1874
|
+
webhookSecret: string;
|
|
1875
|
+
apiUrl?: string;
|
|
1876
|
+
configuredAt: string;
|
|
1877
|
+
}
|
|
1878
|
+
interface PhoneMissionTranscriptEntry {
|
|
1879
|
+
at: string;
|
|
1880
|
+
source: 'system' | 'provider' | 'agent' | 'operator';
|
|
1881
|
+
text: string;
|
|
1882
|
+
metadata?: Record<string, unknown>;
|
|
1883
|
+
}
|
|
1884
|
+
interface PhoneCallMission {
|
|
1885
|
+
id: string;
|
|
1886
|
+
agentId: string;
|
|
1887
|
+
status: PhoneMissionState;
|
|
1888
|
+
from: string;
|
|
1889
|
+
to: string;
|
|
1890
|
+
task: string;
|
|
1891
|
+
policy: OpenClawPhoneMissionPolicy;
|
|
1892
|
+
transport: PhoneTransportProfile;
|
|
1893
|
+
provider: PhoneTransportProvider;
|
|
1894
|
+
providerCallId?: string;
|
|
1895
|
+
transcript: PhoneMissionTranscriptEntry[];
|
|
1896
|
+
metadata: Record<string, unknown>;
|
|
1897
|
+
createdAt: string;
|
|
1898
|
+
updatedAt: string;
|
|
1899
|
+
}
|
|
1900
|
+
interface StartPhoneCallOptions {
|
|
1901
|
+
dryRun?: boolean;
|
|
1902
|
+
fetchFn?: typeof fetch;
|
|
1903
|
+
now?: Date;
|
|
1904
|
+
}
|
|
1905
|
+
interface StartPhoneCallResult {
|
|
1906
|
+
mission: PhoneCallMission;
|
|
1907
|
+
providerRequest?: {
|
|
1908
|
+
url: string;
|
|
1909
|
+
body: Record<string, string>;
|
|
1910
|
+
};
|
|
1911
|
+
providerResponse?: unknown;
|
|
1912
|
+
}
|
|
1913
|
+
interface PhoneWebhookResult {
|
|
1914
|
+
mission: PhoneCallMission;
|
|
1915
|
+
action: Record<string, unknown>;
|
|
1916
|
+
}
|
|
1917
|
+
declare function redactPhoneTransportConfig(config: PhoneTransportConfig): PhoneTransportConfig;
|
|
1918
|
+
declare class PhoneManager {
|
|
1919
|
+
private db;
|
|
1920
|
+
private encryptionKey?;
|
|
1921
|
+
private initialized;
|
|
1922
|
+
/** Per-agent outbound-call timestamps (ms) for the in-memory rate limiter. */
|
|
1923
|
+
private readonly callTimestamps;
|
|
1924
|
+
constructor(db: Database, encryptionKey?: string | undefined);
|
|
1925
|
+
/**
|
|
1926
|
+
* Abuse / cost gate for /calls/start (#43-H1). Each non-dry-run call is
|
|
1927
|
+
* a real billed outbound call, so before dialing we enforce:
|
|
1928
|
+
* - a hard cap on concurrently-active (non-terminal) missions, and
|
|
1929
|
+
* - a per-agent token-bucket rate limit (per-minute + per-hour).
|
|
1930
|
+
* Throws {@link PhoneRateLimitError} (-> HTTP 429) when a limit is hit.
|
|
1931
|
+
* Call only on the real path — dry runs place no call and are exempt.
|
|
1932
|
+
*/
|
|
1933
|
+
private enforceCallLimits;
|
|
1934
|
+
private encryptConfig;
|
|
1935
|
+
private decryptConfig;
|
|
1936
|
+
private ensureTables;
|
|
1937
|
+
getPhoneTransportConfig(agentId: string): PhoneTransportConfig | null;
|
|
1938
|
+
savePhoneTransportConfig(agentId: string, config: PhoneTransportConfig): PhoneTransportConfig;
|
|
1939
|
+
getMission(missionId: string, agentId?: string): PhoneCallMission | null;
|
|
1940
|
+
listMissions(agentId: string, opts?: {
|
|
1941
|
+
limit?: number;
|
|
1942
|
+
offset?: number;
|
|
1943
|
+
status?: PhoneMissionState;
|
|
1944
|
+
}): PhoneCallMission[];
|
|
1945
|
+
startMission(agentId: string, input: StartPhoneMissionInput, options?: StartPhoneCallOptions): Promise<StartPhoneCallResult>;
|
|
1946
|
+
/**
|
|
1947
|
+
* Verify a webhook request and return the mission, or throw a uniform
|
|
1948
|
+
* {@link PhoneWebhookAuthError} for ANY failure (unknown mission, no
|
|
1949
|
+
* token, wrong token). Uniform on purpose — no 404-vs-403 oracle.
|
|
1950
|
+
*/
|
|
1951
|
+
private authenticateWebhook;
|
|
1952
|
+
handleVoiceStartWebhook(missionId: string, providedToken: string, payload?: Record<string, unknown>): PhoneWebhookResult;
|
|
1953
|
+
handleHangupWebhook(missionId: string, providedToken: string, payload?: Record<string, unknown>): PhoneCallMission;
|
|
1954
|
+
/**
|
|
1955
|
+
* Read the call cost off a 46elks hangup payload, add it to the
|
|
1956
|
+
* mission's running total, and flag a policy-cap breach (#43-H2).
|
|
1957
|
+
* Cost is only knowable post-call from the provider — the preventive
|
|
1958
|
+
* cost controls are the duration ceiling, rate limit, and concurrency
|
|
1959
|
+
* cap; this is the after-the-fact accounting + alerting.
|
|
1960
|
+
*/
|
|
1961
|
+
private buildCostMetadataPatch;
|
|
1962
|
+
private buildVoiceStartAction;
|
|
1963
|
+
cancelMission(agentId: string, missionId: string): PhoneCallMission;
|
|
1964
|
+
private build46ElksCallRequest;
|
|
1965
|
+
private insertMission;
|
|
1966
|
+
private updateProviderCall;
|
|
1967
|
+
private updateMissionStatus;
|
|
1968
|
+
}
|
|
1969
|
+
declare function buildPhoneTransportConfig(input: {
|
|
1970
|
+
provider?: unknown;
|
|
1971
|
+
phoneNumber?: unknown;
|
|
1972
|
+
username?: unknown;
|
|
1973
|
+
password?: unknown;
|
|
1974
|
+
webhookBaseUrl?: unknown;
|
|
1975
|
+
webhookSecret?: unknown;
|
|
1976
|
+
apiUrl?: unknown;
|
|
1977
|
+
capabilities?: unknown;
|
|
1978
|
+
supportedRegions?: unknown;
|
|
1979
|
+
configuredAt?: string;
|
|
1980
|
+
}): PhoneTransportConfig;
|
|
1981
|
+
|
|
1695
1982
|
/**
|
|
1696
1983
|
* AgenticMail Anonymous Telemetry
|
|
1697
1984
|
*
|
|
@@ -2735,4 +3022,213 @@ declare class AgentMemoryStore {
|
|
|
2735
3022
|
renderForPrompt(memory: AgentMemoryRead | null): string;
|
|
2736
3023
|
}
|
|
2737
3024
|
|
|
2738
|
-
|
|
3025
|
+
/**
|
|
3026
|
+
* Agent Memory Manager — persistent, evolving per-agent memory.
|
|
3027
|
+
*
|
|
3028
|
+
* Ported from the AgenticMail Enterprise engine memory system and
|
|
3029
|
+
* adapted for the open-source single-tenant package: the multi-tenant
|
|
3030
|
+
* `orgId` / organization concepts have been removed (memory here is
|
|
3031
|
+
* personal to each agent), the database layer is the built-in
|
|
3032
|
+
* `node:sqlite` `Database`, and agent deletion fully purges memory.
|
|
3033
|
+
*
|
|
3034
|
+
* Each agent gets a growing knowledge store that evolves over time,
|
|
3035
|
+
* the way a human employee learns on the job:
|
|
3036
|
+
* - Category-based organisation (knowledge, preference, correction,
|
|
3037
|
+
* skill, context, reflection, …).
|
|
3038
|
+
* - Importance levels (critical / high / normal / low).
|
|
3039
|
+
* - Confidence scores that decay for entries left unaccessed.
|
|
3040
|
+
* - Access tracking so frequently-used knowledge ranks higher.
|
|
3041
|
+
* - `generateMemoryContext()` — ranks + renders memory as a markdown
|
|
3042
|
+
* block for injection into an agent's prompt (or a voice session).
|
|
3043
|
+
* - Pruning of expired / low-confidence entries.
|
|
3044
|
+
*
|
|
3045
|
+
* Design: an in-memory `Map` + BM25F search index fronts the
|
|
3046
|
+
* `agent_memory` SQLite table. Reads hit memory; writes update both.
|
|
3047
|
+
*/
|
|
3048
|
+
|
|
3049
|
+
type MemoryCategory = 'knowledge' | 'interaction_pattern' | 'preference' | 'correction' | 'skill' | 'context' | 'reflection' | 'session_learning' | 'system_notice';
|
|
3050
|
+
type MemoryImportance = 'critical' | 'high' | 'normal' | 'low';
|
|
3051
|
+
type MemorySource = 'interaction' | 'self_reflection' | 'correction' | 'system' | 'context_compaction' | 'transfer';
|
|
3052
|
+
declare const MEMORY_CATEGORIES: Record<MemoryCategory, {
|
|
3053
|
+
label: string;
|
|
3054
|
+
description: string;
|
|
3055
|
+
}>;
|
|
3056
|
+
interface AgentMemoryEntry {
|
|
3057
|
+
id: string;
|
|
3058
|
+
agentId: string;
|
|
3059
|
+
category: MemoryCategory;
|
|
3060
|
+
title: string;
|
|
3061
|
+
content: string;
|
|
3062
|
+
source: MemorySource;
|
|
3063
|
+
importance: MemoryImportance;
|
|
3064
|
+
confidence: number;
|
|
3065
|
+
accessCount: number;
|
|
3066
|
+
lastAccessedAt?: string;
|
|
3067
|
+
expiresAt?: string;
|
|
3068
|
+
tags: string[];
|
|
3069
|
+
metadata: Record<string, any>;
|
|
3070
|
+
createdAt: string;
|
|
3071
|
+
updatedAt: string;
|
|
3072
|
+
}
|
|
3073
|
+
interface MemoryStats {
|
|
3074
|
+
totalEntries: number;
|
|
3075
|
+
byCategory: Record<string, number>;
|
|
3076
|
+
byImportance: Record<string, number>;
|
|
3077
|
+
bySource: Record<string, number>;
|
|
3078
|
+
avgConfidence: number;
|
|
3079
|
+
}
|
|
3080
|
+
/** Input shape for createMemory — id, timestamps, accessCount, and some fields have defaults. */
|
|
3081
|
+
type CreateMemoryInput = Omit<AgentMemoryEntry, 'id' | 'createdAt' | 'updatedAt' | 'accessCount' | 'confidence' | 'tags' | 'metadata' | 'lastAccessedAt' | 'expiresAt'> & {
|
|
3082
|
+
confidence?: number;
|
|
3083
|
+
tags?: string[];
|
|
3084
|
+
metadata?: Record<string, any>;
|
|
3085
|
+
lastAccessedAt?: string;
|
|
3086
|
+
expiresAt?: string;
|
|
3087
|
+
};
|
|
3088
|
+
/** Input shape for updateMemory — partial updates merged with existing entry. */
|
|
3089
|
+
type UpdateMemoryInput = Partial<Omit<AgentMemoryEntry, 'id' | 'agentId' | 'createdAt'>>;
|
|
3090
|
+
/** Query options for filtering memory entries. */
|
|
3091
|
+
interface MemoryQueryOptions {
|
|
3092
|
+
agentId: string;
|
|
3093
|
+
category?: string;
|
|
3094
|
+
importance?: string;
|
|
3095
|
+
source?: string;
|
|
3096
|
+
query?: string;
|
|
3097
|
+
limit?: number;
|
|
3098
|
+
}
|
|
3099
|
+
declare class AgentMemoryManager {
|
|
3100
|
+
private db;
|
|
3101
|
+
private memories;
|
|
3102
|
+
/** Per-agent index: agentId → Set of memory IDs for O(1) agent lookups */
|
|
3103
|
+
private agentIndex;
|
|
3104
|
+
/** Full-text search index (BM25F + stemming + inverted index) */
|
|
3105
|
+
private searchIndex;
|
|
3106
|
+
private initialized;
|
|
3107
|
+
constructor(db: Database);
|
|
3108
|
+
private ensureTable;
|
|
3109
|
+
/** Run a write statement, swallowing errors with a log (memory must never crash a caller). */
|
|
3110
|
+
private dbRun;
|
|
3111
|
+
private dbAll;
|
|
3112
|
+
private loadFromDb;
|
|
3113
|
+
/** Add a memory ID to the per-agent index. */
|
|
3114
|
+
private indexAdd;
|
|
3115
|
+
/** Remove a memory ID from the per-agent index. */
|
|
3116
|
+
private indexRemove;
|
|
3117
|
+
/** Get all memory entries for an agent via the index. */
|
|
3118
|
+
private getAgentMemories;
|
|
3119
|
+
/** Store a memory with minimal input — the common "just remember this" case. */
|
|
3120
|
+
storeMemory(agentId: string, opts: {
|
|
3121
|
+
content: string;
|
|
3122
|
+
category?: string;
|
|
3123
|
+
importance?: string;
|
|
3124
|
+
confidence?: number;
|
|
3125
|
+
title?: string;
|
|
3126
|
+
tags?: string[];
|
|
3127
|
+
}): Promise<AgentMemoryEntry>;
|
|
3128
|
+
/** Search memories by text query, sorted by relevance. */
|
|
3129
|
+
recall(agentId: string, query: string, limit?: number): Promise<AgentMemoryEntry[]>;
|
|
3130
|
+
/** Create a new memory entry with auto-generated id + timestamps. */
|
|
3131
|
+
createMemory(input: CreateMemoryInput): Promise<AgentMemoryEntry>;
|
|
3132
|
+
/** Update an existing memory entry by merging provided fields. */
|
|
3133
|
+
updateMemory(id: string, updates: UpdateMemoryInput): Promise<AgentMemoryEntry | null>;
|
|
3134
|
+
/** Delete a single memory entry. Returns true if it existed. */
|
|
3135
|
+
deleteMemory(id: string): Promise<boolean>;
|
|
3136
|
+
/**
|
|
3137
|
+
* Purge every memory entry belonging to an agent — Map, per-agent
|
|
3138
|
+
* index, search index, and the database row. Called when an agent is
|
|
3139
|
+
* deleted so no orphaned memory is left behind.
|
|
3140
|
+
* Returns the number of entries removed.
|
|
3141
|
+
*/
|
|
3142
|
+
deleteAgentMemories(agentId: string): Promise<number>;
|
|
3143
|
+
/** Retrieve a single memory entry by id. */
|
|
3144
|
+
getMemory(id: string): Promise<AgentMemoryEntry | undefined>;
|
|
3145
|
+
/** Query an agent's memory with optional category/importance/source filters + text search. */
|
|
3146
|
+
queryMemories(opts: MemoryQueryOptions): Promise<AgentMemoryEntry[]>;
|
|
3147
|
+
/** Memories created within the last N hours for an agent. */
|
|
3148
|
+
getRecentMemories(agentId: string, hours?: number): Promise<AgentMemoryEntry[]>;
|
|
3149
|
+
/** Bump access count + lastAccessedAt for a memory entry. */
|
|
3150
|
+
recordAccess(memoryId: string): Promise<void>;
|
|
3151
|
+
/**
|
|
3152
|
+
* Render an agent's memory as a markdown block for prompt injection.
|
|
3153
|
+
* Ranks entries by confidence × access × recency × importance, with a
|
|
3154
|
+
* BM25F relevance boost when a query is supplied, groups by category,
|
|
3155
|
+
* and truncates to ~maxTokens (estimated at 4 chars/token).
|
|
3156
|
+
*/
|
|
3157
|
+
generateMemoryContext(agentId: string, query?: string, maxTokens?: number): Promise<string>;
|
|
3158
|
+
/** Decay confidence for entries unaccessed for 7+ days. Critical entries are exempt. */
|
|
3159
|
+
decayConfidence(agentId: string, decayRate?: number): Promise<number>;
|
|
3160
|
+
/** Prune entries with confidence < 0.1 or past their expiresAt. */
|
|
3161
|
+
pruneExpired(agentId?: string): Promise<number>;
|
|
3162
|
+
/** Aggregate statistics for a specific agent's memory. */
|
|
3163
|
+
getStats(agentId: string): Promise<MemoryStats>;
|
|
3164
|
+
private computeStats;
|
|
3165
|
+
private rowToEntry;
|
|
3166
|
+
}
|
|
3167
|
+
|
|
3168
|
+
declare function stem(word: string): string;
|
|
3169
|
+
/** Tokenize text into stemmed, lowercase terms, filtering stop words. */
|
|
3170
|
+
declare function tokenize(text: string): string[];
|
|
3171
|
+
/**
|
|
3172
|
+
* Pre-built inverted index for fast text search.
|
|
3173
|
+
* Maintained incrementally — no re-indexing needed on queries.
|
|
3174
|
+
*
|
|
3175
|
+
* Structure:
|
|
3176
|
+
* term → Set<docId> (posting list — which docs contain this term)
|
|
3177
|
+
* prefixMap: prefix → Set<stem> (3-char prefixes → full stems for prefix matching)
|
|
3178
|
+
* docs: docId → DocRecord (per-doc weighted TF and length)
|
|
3179
|
+
* idf: term → number (pre-computed IDF, refreshed on mutations)
|
|
3180
|
+
*/
|
|
3181
|
+
declare class MemorySearchIndex {
|
|
3182
|
+
/** Posting lists: stemmed term → Set of memory IDs containing it */
|
|
3183
|
+
private postings;
|
|
3184
|
+
/** Per-document metadata for BM25 scoring */
|
|
3185
|
+
private docs;
|
|
3186
|
+
/** Pre-computed IDF values. Stale flag triggers lazy recomputation. */
|
|
3187
|
+
private idf;
|
|
3188
|
+
private idfStale;
|
|
3189
|
+
/** 3-character prefix map for prefix matching: prefix → Set of full stems */
|
|
3190
|
+
private prefixMap;
|
|
3191
|
+
/** Total weighted document length (for computing average) */
|
|
3192
|
+
private totalWeightedLen;
|
|
3193
|
+
get docCount(): number;
|
|
3194
|
+
get avgDocLen(): number;
|
|
3195
|
+
/**
|
|
3196
|
+
* Index a memory entry. Extracts stems from title, content, and tags
|
|
3197
|
+
* with field-specific weighting and builds posting lists.
|
|
3198
|
+
*/
|
|
3199
|
+
addDocument(id: string, entry: {
|
|
3200
|
+
title: string;
|
|
3201
|
+
content: string;
|
|
3202
|
+
tags: string[];
|
|
3203
|
+
}): void;
|
|
3204
|
+
/** Remove a document from the index. */
|
|
3205
|
+
removeDocument(id: string): void;
|
|
3206
|
+
/** Recompute IDF values for all terms. Called lazily before search. */
|
|
3207
|
+
private refreshIdf;
|
|
3208
|
+
/**
|
|
3209
|
+
* Expand query terms with prefix matches.
|
|
3210
|
+
* "deploy" → ["deploy", "deployment", "deploying", ...] (if they exist in the index)
|
|
3211
|
+
*/
|
|
3212
|
+
private expandQueryTerms;
|
|
3213
|
+
/**
|
|
3214
|
+
* Compute bigram proximity boost: if two query terms appear adjacent
|
|
3215
|
+
* in the document's stem sequence, boost the score.
|
|
3216
|
+
*/
|
|
3217
|
+
private bigramProximityBoost;
|
|
3218
|
+
/**
|
|
3219
|
+
* Search the index for documents matching a query.
|
|
3220
|
+
* Returns scored results sorted by BM25F relevance.
|
|
3221
|
+
*
|
|
3222
|
+
* @param query - Raw query string
|
|
3223
|
+
* @param candidateIds - Optional: only score these document IDs (for agent-scoped search)
|
|
3224
|
+
* @returns Array of { id, score } sorted by descending score
|
|
3225
|
+
*/
|
|
3226
|
+
search(query: string, candidateIds?: Set<string>): Array<{
|
|
3227
|
+
id: string;
|
|
3228
|
+
score: number;
|
|
3229
|
+
}>;
|
|
3230
|
+
/** Check if a document exists in the index. */
|
|
3231
|
+
has(id: string): boolean;
|
|
3232
|
+
}
|
|
3233
|
+
|
|
3234
|
+
export { AGENT_ROLES, AccountManager, type AddressInfo, type Agent, AgentDeletionService, type AgentMemoryEntry, type AgentMemoryFields, AgentMemoryManager, type AgentMemoryOptions, type AgentMemoryRead, AgentMemoryStore, type AgentRole, AgenticMailClient, type AgenticMailClientOptions, type AgenticMailConfig, type ArchiveAndDeleteOptions, type ArchivedEmail, type Attachment, type AttachmentAdvisory, BRIDGE_OPERATOR_LIVE_WINDOW_MS, type BridgeMailContext, type BridgeWakeError, type BridgeWakePromptArgs, type BridgeWakeResult, type BridgeWakeRoute, type CachedMessage, CloudflareClient, type CreateAgentOptions, type CreateMemoryInput, DEFAULT_AGENT_NAME, DEFAULT_AGENT_ROLE, DEFAULT_SESSION_MAX_AGE_MS, DNSConfigurator, type Database, type DeletionReport, type DeletionSummary, DependencyChecker, DependencyInstaller, type DependencyStatus, type DnsRecord, type DnsSetupResult, type DomainInfo, DomainManager, type DomainModeConfig, type DomainPurchaseResult, DomainPurchaser, type DomainSearchResult, type DomainSetupResult, ELKS_REALTIME_AUDIO_FORMATS, type ElksRealtimeAudioFormat, type ElksRealtimeAudioMessage, type ElksRealtimeByeMessage, type ElksRealtimeHelloMessage, type ElksRealtimeInboundMessage, type ElksRealtimeOutboundMessage, type EmailEnvelope, type EmailRouteAction, type EmailRouteClass, type EmailRouteClassification, type EmailRouteInput, EmailSearchIndex, type FolderInfo, type GatewayConfig, GatewayManager, type GatewayManagerOptions, type GatewayMode, type GatewayStatus, type HostName, type HostSession, type HostSessionResumeMode, type InboundEmail, type InboundSmsEvent, type InboxEvent, type InboxExpungeEvent, type InboxFlagsEvent, type InboxNewEvent, InboxWatcher, type InboxWatcherOptions, type InstallProgress, type LinkAdvisory, type LocalSmtpConfig, MEMORY_CATEGORIES, MailReceiver, type MailReceiverOptions, MailSender, type MailSenderOptions, type MailboxInfo, type MemoryCategory, type MemoryImportance, type MemoryQueryOptions, MemorySearchIndex, type MemorySource, type MemoryStats, type OpenClawPhoneMissionPolicy, type OutboundCategory, type OutboundScanInput, type OutboundScanResult, type OutboundWarning, PHONE_MAX_CONCURRENT_MISSIONS, PHONE_MIN_WEBHOOK_SECRET_LENGTH, PHONE_MISSION_STATES, PHONE_RATE_LIMIT_PER_HOUR, PHONE_RATE_LIMIT_PER_MINUTE, PHONE_REGION_SCOPES, PHONE_SERVER_MAX_ATTEMPTS, PHONE_SERVER_MAX_CALL_DURATION_SECONDS, PHONE_SERVER_MAX_COST_PER_MISSION, PHONE_TASK_MAX_LENGTH, type ParsedAttachment, type ParsedEmail, type ParsedSms, PathTraversalError, type PhoneAlternativePolicy, type PhoneCallMission, type PhoneConfirmPolicy, PhoneManager, type PhoneMissionStartValidationResult, type PhoneMissionState, type PhoneMissionTranscriptEntry, type PhoneMissionValidationIssue, type PhoneMissionValidationResult, type PhoneNumberRisk, PhoneRateLimitError, type PhoneRegionScope, type PhoneTransportConfig, type PhoneTransportProfile, type PhoneTransportProvider, type PhoneTransportValidationResult, PhoneWebhookAuthError, type PhoneWebhookResult, type PlanBridgeWakeArgs, type PurchasedDomain, REDACTED, RELAY_PRESETS, RelayBridge, type RelayBridgeOptions, type RelayConfig, RelayGateway, type RelayProvider, type RelaySearchResult, type ResumeErrorClassificationOptions, SPAM_THRESHOLD, type SafeJoinOptions, type SanitizeDetection, type SanitizeResult, type SearchCriteria, type SearchableEmail, type SecurityAdvisory, type SendMailOptions, type SendResult, type SendResultWithRaw, type SendSmsInput, type SendSmsResult, ServiceManager, type ServiceStatus, type SetupConfig, SetupManager, type SetupResult, type Severity, type SmsConfig, SmsManager, type SmsMessage, SmsPoller, type SmsProvider, type SpamCategory, type SpamResult, type SpamRuleMatch, StalwartAdmin, type StalwartAdminOptions, type StalwartPrincipal, type StartPhoneCallOptions, type StartPhoneCallResult, type StartPhoneMissionInput, TELEPHONY_TRANSPORT_CAPABILITIES, type TelephonyTransportCapability, ThreadCache, type ThreadCacheEntry, type ThreadCacheOptions, type ThreadIdInput, type TunnelConfig, TunnelManager, UnsafeApiUrlError, type UpdateMemoryInput, type ValidatedPhoneMissionStart, WARNING_THRESHOLD, type WatcherOptions, assertWithinBase, bridgeWakeErrorMessage, bridgeWakeLastSeenAgeMs, buildApiUrl, buildElksAudioMessage, buildElksByeMessage, buildElksHandshakeMessages, buildElksInterruptMessage, buildElksListeningMessage, buildElksSendingMessage, buildInboundSecurityAdvisory, buildPhoneTransportConfig, classifyEmailRoute, classifyPhoneNumberRisk, classifyResumeError, closeDatabase, composeBridgeWakePrompt, createTestDatabase, debug, debugWarn, ensureDataDir, extractVerificationCode, flushTelemetry, forgetHostSession, getDatabase, getOperatorEmail, getSmsProvider, hostSessionStoragePath, inferPhoneRegion, isInternalEmail, isLoopbackMailHost, isPhoneRegionAllowed, isSessionFresh, isValidPhoneNumber, loadHostSession, mapProviderSmsStatus, normalizeAddress, normalizePhoneNumber, normalizeSubject, operatorPrefsStoragePath, parseElksRealtimeMessage, parseEmail, parseGoogleVoiceSms, planBridgeWake, recordToolCall, redactObject, redactPhoneTransportConfig, redactSecret, redactSmsConfig, resolveConfig, resolveTlsRejectUnauthorized, safeJoin, sanitizeEmail, saveConfig, saveHostSession, scanOutboundEmail, scoreEmail, setOperatorEmail, setTelemetryVersion, shouldSkipBridgeWakeForLiveOperator, startRelayBridge, stem, threadIdFor, tokenize, tryJoin, validateApiUrl, validatePhoneMissionPolicy, validatePhoneMissionStart, validatePhoneTransportProfile };
|