@agenticmail/core 0.9.28 → 0.9.30

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 CHANGED
@@ -1459,6 +1459,8 @@ __export(index_exports, {
1459
1459
  CloudflareClient: () => CloudflareClient,
1460
1460
  DEFAULT_AGENT_NAME: () => DEFAULT_AGENT_NAME,
1461
1461
  DEFAULT_AGENT_ROLE: () => DEFAULT_AGENT_ROLE,
1462
+ DEFAULT_CALLBACK_POLICY: () => DEFAULT_CALLBACK_POLICY,
1463
+ DEFAULT_EXTENSION_POLICY: () => DEFAULT_EXTENSION_POLICY,
1462
1464
  DEFAULT_REALTIME_AUDIO_FORMAT: () => DEFAULT_REALTIME_AUDIO_FORMAT,
1463
1465
  DEFAULT_REALTIME_MODEL: () => DEFAULT_REALTIME_MODEL,
1464
1466
  DEFAULT_REALTIME_VOICE: () => DEFAULT_REALTIME_VOICE,
@@ -1471,8 +1473,11 @@ __export(index_exports, {
1471
1473
  DomainPurchaser: () => DomainPurchaser,
1472
1474
  ELKS_REALTIME_AUDIO_FORMATS: () => ELKS_REALTIME_AUDIO_FORMATS,
1473
1475
  ELKS_REALTIME_WS_PATH: () => ELKS_REALTIME_WS_PATH,
1476
+ END_CALL_TOOL: () => END_CALL_TOOL,
1477
+ EXTEND_CALL_TIME_TOOL: () => EXTEND_CALL_TIME_TOOL,
1474
1478
  ElksRealtimeTransport: () => ElksRealtimeTransport,
1475
1479
  EmailSearchIndex: () => EmailSearchIndex,
1480
+ GET_CALL_STATUS_TOOL: () => GET_CALL_STATUS_TOOL,
1476
1481
  GET_DATETIME_TOOL: () => GET_DATETIME_TOOL,
1477
1482
  GatewayManager: () => GatewayManager,
1478
1483
  InboxWatcher: () => InboxWatcher,
@@ -1487,6 +1492,8 @@ __export(index_exports, {
1487
1492
  OPERATOR_QUERY_SUBJECT_TAG: () => OPERATOR_QUERY_SUBJECT_TAG,
1488
1493
  OPERATOR_QUERY_TIMEOUT_MS: () => OPERATOR_QUERY_TIMEOUT_MS,
1489
1494
  OPERATOR_QUERY_TIMEOUT_SENTINEL: () => OPERATOR_QUERY_TIMEOUT_SENTINEL,
1495
+ PHONE_CALLBACK_MAX_DELAY_SECONDS: () => PHONE_CALLBACK_MAX_DELAY_SECONDS,
1496
+ PHONE_CALLBACK_MIN_DELAY_SECONDS: () => PHONE_CALLBACK_MIN_DELAY_SECONDS,
1490
1497
  PHONE_CALL_CONTROL_PROVIDERS: () => PHONE_CALL_CONTROL_PROVIDERS,
1491
1498
  PHONE_MAX_CONCURRENT_MISSIONS: () => PHONE_MAX_CONCURRENT_MISSIONS,
1492
1499
  PHONE_MIN_WEBHOOK_SECRET_LENGTH: () => PHONE_MIN_WEBHOOK_SECRET_LENGTH,
@@ -1495,8 +1502,12 @@ __export(index_exports, {
1495
1502
  PHONE_RATE_LIMIT_PER_MINUTE: () => PHONE_RATE_LIMIT_PER_MINUTE,
1496
1503
  PHONE_REGION_SCOPES: () => PHONE_REGION_SCOPES,
1497
1504
  PHONE_SERVER_MAX_ATTEMPTS: () => PHONE_SERVER_MAX_ATTEMPTS,
1505
+ PHONE_SERVER_MAX_CALLBACK_CHAIN: () => PHONE_SERVER_MAX_CALLBACK_CHAIN,
1498
1506
  PHONE_SERVER_MAX_CALL_DURATION_SECONDS: () => PHONE_SERVER_MAX_CALL_DURATION_SECONDS,
1499
1507
  PHONE_SERVER_MAX_COST_PER_MISSION: () => PHONE_SERVER_MAX_COST_PER_MISSION,
1508
+ PHONE_SERVER_MAX_EXTENSION_REQUESTS_PER_CALL: () => PHONE_SERVER_MAX_EXTENSION_REQUESTS_PER_CALL,
1509
+ PHONE_SERVER_MAX_EXTENSION_SECONDS_PER_REQUEST: () => PHONE_SERVER_MAX_EXTENSION_SECONDS_PER_REQUEST,
1510
+ PHONE_SERVER_MAX_TOTAL_EXTENSION_SECONDS: () => PHONE_SERVER_MAX_TOTAL_EXTENSION_SECONDS,
1500
1511
  PHONE_TASK_MAX_LENGTH: () => PHONE_TASK_MAX_LENGTH,
1501
1512
  PathTraversalError: () => PathTraversalError,
1502
1513
  PhoneManager: () => PhoneManager,
@@ -1512,6 +1523,7 @@ __export(index_exports, {
1512
1523
  RealtimeVoiceBridge: () => RealtimeVoiceBridge,
1513
1524
  RelayBridge: () => RelayBridge,
1514
1525
  RelayGateway: () => RelayGateway,
1526
+ SCHEDULE_CALLBACK_TOOL: () => SCHEDULE_CALLBACK_TOOL,
1515
1527
  SEARCH_EMAIL_TOOL: () => SEARCH_EMAIL_TOOL,
1516
1528
  SEARCH_SKILLS_TOOL: () => SEARCH_SKILLS_TOOL,
1517
1529
  SPAM_THRESHOLD: () => SPAM_THRESHOLD,
@@ -1632,7 +1644,9 @@ __export(index_exports, {
1632
1644
  renderSkillAsPrompt: () => renderSkillAsPrompt,
1633
1645
  requireBinary: () => requireBinary,
1634
1646
  requireWhisperModel: () => requireWhisperModel,
1647
+ resolveCallbackPolicy: () => resolveCallbackPolicy,
1635
1648
  resolveConfig: () => resolveConfig,
1649
+ resolveExtensionPolicy: () => resolveExtensionPolicy,
1636
1650
  resolveTlsRejectUnauthorized: () => resolveTlsRejectUnauthorized,
1637
1651
  safeJoin: () => safeJoin,
1638
1652
  sanitizeEmail: () => sanitizeEmail,
@@ -7533,6 +7547,7 @@ var DEFAULT_CALLBACK_POLICY = {
7533
7547
  allowAutoCallback: true,
7534
7548
  maxCallbackChain: 2
7535
7549
  };
7550
+ var PHONE_CALLBACK_MIN_DELAY_SECONDS = 30;
7536
7551
  var PHONE_CALLBACK_MAX_DELAY_SECONDS = 7 * 24 * 60 * 60;
7537
7552
  var EU_DIAL_PREFIXES = [
7538
7553
  "+30",
@@ -13320,6 +13335,24 @@ var ServiceManager = class {
13320
13335
  "",
13321
13336
  'log "AgenticMail starting..."',
13322
13337
  "",
13338
+ "# v0.9.84 \u2014 source ~/.agenticmail/.env before exec so the API process",
13339
+ "# inherits AGENTICMAIL_MASTER_KEY, AGENTICMAIL_INBOUND_SECRET, the",
13340
+ "# Stalwart admin creds, and SMTP/IMAP/data-dir overrides. Without",
13341
+ "# this, launchd's child ran with only HOME / PATH / DATA_DIR (the",
13342
+ "# plist EnvironmentVariables block), so the API silently fell back",
13343
+ "# to a fresh-random INBOUND_SECRET on every boot and could not",
13344
+ "# decrypt master-key-protected secrets at all.",
13345
+ 'ENV_FILE="$HOME/.agenticmail/.env"',
13346
+ 'if [ -f "$ENV_FILE" ]; then',
13347
+ ' log "Sourcing $ENV_FILE"',
13348
+ " set -a # mark all sourced vars for export",
13349
+ " # shellcheck disable=SC1090",
13350
+ ' . "$ENV_FILE"',
13351
+ " set +a",
13352
+ "else",
13353
+ ' log "WARNING: $ENV_FILE not found \u2014 API will run with default config (no master key)."',
13354
+ "fi",
13355
+ "",
13323
13356
  "# Wait for Docker daemon (up to 10 minutes \u2014 Docker Desktop can be very slow on first boot)",
13324
13357
  "MAX_WAIT=600",
13325
13358
  "WAITED=0",
@@ -13745,6 +13778,16 @@ var SetupManager = class {
13745
13778
  if ((0, import_node_fs10.existsSync)(configPath)) {
13746
13779
  try {
13747
13780
  const existing = JSON.parse((0, import_node_fs10.readFileSync)(configPath, "utf-8"));
13781
+ let needsRewrite = false;
13782
+ if (!existing.inboundSecret) {
13783
+ existing.inboundSecret = `inb_${(0, import_node_crypto6.randomBytes)(24).toString("hex")}`;
13784
+ needsRewrite = true;
13785
+ }
13786
+ if (needsRewrite) {
13787
+ (0, import_node_fs10.writeFileSync)(configPath, JSON.stringify(existing, null, 2));
13788
+ (0, import_node_fs10.chmodSync)(configPath, 384);
13789
+ this.ensureEnvHasInboundSecret(envPath, existing.inboundSecret);
13790
+ }
13748
13791
  this.generateDockerFiles(existing);
13749
13792
  return { configPath, envPath, config: existing, isNew: false };
13750
13793
  } catch {
@@ -13755,8 +13798,10 @@ var SetupManager = class {
13755
13798
  }
13756
13799
  const masterKey = `mk_${(0, import_node_crypto6.randomBytes)(24).toString("hex")}`;
13757
13800
  const stalwartPassword = (0, import_node_crypto6.randomBytes)(16).toString("hex");
13801
+ const inboundSecret = `inb_${(0, import_node_crypto6.randomBytes)(24).toString("hex")}`;
13758
13802
  const config = {
13759
13803
  masterKey,
13804
+ inboundSecret,
13760
13805
  stalwart: {
13761
13806
  url: "http://localhost:8080",
13762
13807
  adminUser: "admin",
@@ -13775,6 +13820,7 @@ STALWART_ADMIN_PASSWORD=${stalwartPassword}
13775
13820
  STALWART_URL=http://localhost:8080
13776
13821
 
13777
13822
  AGENTICMAIL_MASTER_KEY=${masterKey}
13823
+ AGENTICMAIL_INBOUND_SECRET=${inboundSecret}
13778
13824
  AGENTICMAIL_API_PORT=3829
13779
13825
  AGENTICMAIL_DATA_DIR=${dataDir}
13780
13826
 
@@ -13788,6 +13834,24 @@ IMAP_PORT=143
13788
13834
  this.generateDockerFiles(config);
13789
13835
  return { configPath, envPath, config, isNew: true };
13790
13836
  }
13837
+ /**
13838
+ * Append `AGENTICMAIL_INBOUND_SECRET=...` to .env if the file does
13839
+ * not already contain that key. Used by the lazy-mint path to make
13840
+ * sure existing installs pick up the new secret on next boot
13841
+ * without clobbering anything the operator added.
13842
+ */
13843
+ ensureEnvHasInboundSecret(envPath, secret) {
13844
+ if (!(0, import_node_fs10.existsSync)(envPath)) return;
13845
+ try {
13846
+ const current = (0, import_node_fs10.readFileSync)(envPath, "utf-8");
13847
+ if (/^AGENTICMAIL_INBOUND_SECRET=/m.test(current)) return;
13848
+ const updated = current + (current.endsWith("\n") ? "" : "\n") + `AGENTICMAIL_INBOUND_SECRET=${secret}
13849
+ `;
13850
+ (0, import_node_fs10.writeFileSync)(envPath, updated);
13851
+ (0, import_node_fs10.chmodSync)(envPath, 384);
13852
+ } catch {
13853
+ }
13854
+ }
13791
13855
  /**
13792
13856
  * Generate docker-compose.yml and stalwart.toml in ~/.agenticmail/
13793
13857
  * with the correct admin password from config.
@@ -16105,6 +16169,8 @@ init_skills();
16105
16169
  CloudflareClient,
16106
16170
  DEFAULT_AGENT_NAME,
16107
16171
  DEFAULT_AGENT_ROLE,
16172
+ DEFAULT_CALLBACK_POLICY,
16173
+ DEFAULT_EXTENSION_POLICY,
16108
16174
  DEFAULT_REALTIME_AUDIO_FORMAT,
16109
16175
  DEFAULT_REALTIME_MODEL,
16110
16176
  DEFAULT_REALTIME_VOICE,
@@ -16117,8 +16183,11 @@ init_skills();
16117
16183
  DomainPurchaser,
16118
16184
  ELKS_REALTIME_AUDIO_FORMATS,
16119
16185
  ELKS_REALTIME_WS_PATH,
16186
+ END_CALL_TOOL,
16187
+ EXTEND_CALL_TIME_TOOL,
16120
16188
  ElksRealtimeTransport,
16121
16189
  EmailSearchIndex,
16190
+ GET_CALL_STATUS_TOOL,
16122
16191
  GET_DATETIME_TOOL,
16123
16192
  GatewayManager,
16124
16193
  InboxWatcher,
@@ -16133,6 +16202,8 @@ init_skills();
16133
16202
  OPERATOR_QUERY_SUBJECT_TAG,
16134
16203
  OPERATOR_QUERY_TIMEOUT_MS,
16135
16204
  OPERATOR_QUERY_TIMEOUT_SENTINEL,
16205
+ PHONE_CALLBACK_MAX_DELAY_SECONDS,
16206
+ PHONE_CALLBACK_MIN_DELAY_SECONDS,
16136
16207
  PHONE_CALL_CONTROL_PROVIDERS,
16137
16208
  PHONE_MAX_CONCURRENT_MISSIONS,
16138
16209
  PHONE_MIN_WEBHOOK_SECRET_LENGTH,
@@ -16141,8 +16212,12 @@ init_skills();
16141
16212
  PHONE_RATE_LIMIT_PER_MINUTE,
16142
16213
  PHONE_REGION_SCOPES,
16143
16214
  PHONE_SERVER_MAX_ATTEMPTS,
16215
+ PHONE_SERVER_MAX_CALLBACK_CHAIN,
16144
16216
  PHONE_SERVER_MAX_CALL_DURATION_SECONDS,
16145
16217
  PHONE_SERVER_MAX_COST_PER_MISSION,
16218
+ PHONE_SERVER_MAX_EXTENSION_REQUESTS_PER_CALL,
16219
+ PHONE_SERVER_MAX_EXTENSION_SECONDS_PER_REQUEST,
16220
+ PHONE_SERVER_MAX_TOTAL_EXTENSION_SECONDS,
16146
16221
  PHONE_TASK_MAX_LENGTH,
16147
16222
  PathTraversalError,
16148
16223
  PhoneManager,
@@ -16158,6 +16233,7 @@ init_skills();
16158
16233
  RealtimeVoiceBridge,
16159
16234
  RelayBridge,
16160
16235
  RelayGateway,
16236
+ SCHEDULE_CALLBACK_TOOL,
16161
16237
  SEARCH_EMAIL_TOOL,
16162
16238
  SEARCH_SKILLS_TOOL,
16163
16239
  SPAM_THRESHOLD,
@@ -16278,7 +16354,9 @@ init_skills();
16278
16354
  renderSkillAsPrompt,
16279
16355
  requireBinary,
16280
16356
  requireWhisperModel,
16357
+ resolveCallbackPolicy,
16281
16358
  resolveConfig,
16359
+ resolveExtensionPolicy,
16282
16360
  resolveTlsRejectUnauthorized,
16283
16361
  safeJoin,
16284
16362
  sanitizeEmail,
package/dist/index.d.cts CHANGED
@@ -2623,6 +2623,51 @@ declare const PHONE_SERVER_MAX_COST_PER_MISSION = 5;
2623
2623
  declare const PHONE_SERVER_MAX_ATTEMPTS = 3;
2624
2624
  /** Hard cap on the free-text `task` fed to the voice runtime. */
2625
2625
  declare const PHONE_TASK_MAX_LENGTH = 2000;
2626
+ /**
2627
+ * Server-side ceilings for the extension policy. Like the duration /
2628
+ * cost caps above, these are the financial blast-radius bound — a
2629
+ * caller can ask for a stricter extension policy but never a looser
2630
+ * one. The defaults err on the side of "give the agent a fighting
2631
+ * chance to finish a real call" without letting it sit on the line
2632
+ * forever. v0.9.82 bumped these substantially after field reports of
2633
+ * agents running out of time on legitimately long calls (15-25 min
2634
+ * hold queues, 30 min explanations from the rep):
2635
+ *
2636
+ * - per-request cap raised 5 min → 15 min so a single "I need more
2637
+ * time on hold" request can carry the agent through a queue
2638
+ * - per-call cap raised 4 → 8 so chained extensions don't run dry
2639
+ * on a long bureaucracy call
2640
+ * - total cap raised 10 min → 1 hour so the absolute add can match
2641
+ * a long-tail call without artificial chunking
2642
+ *
2643
+ * The TOTAL also can't push the call past
2644
+ * PHONE_SERVER_MAX_CALL_DURATION_SECONDS — that ceiling still wins.
2645
+ */
2646
+ declare const PHONE_SERVER_MAX_EXTENSION_SECONDS_PER_REQUEST = 900;
2647
+ declare const PHONE_SERVER_MAX_EXTENSION_REQUESTS_PER_CALL = 8;
2648
+ declare const PHONE_SERVER_MAX_TOTAL_EXTENSION_SECONDS = 3600;
2649
+ /** Default per-call extension envelope when the caller doesn't set one.
2650
+ * Bumped in v0.9.82 — 5 min × 4 = 20 min of headroom is a much more
2651
+ * realistic out-of-the-box budget for the kinds of calls operators
2652
+ * actually use this for (bills, bookings, customer support). */
2653
+ declare const DEFAULT_EXTENSION_POLICY: PhoneExtensionPolicy;
2654
+ /**
2655
+ * Server-side ceiling on how deep a callback chain can go. Each call
2656
+ * counts; a brand-new mission is depth 0, its callback is depth 1, the
2657
+ * callback's callback is depth 2. Prevents an agent + bot operator on
2658
+ * the other end from getting stuck in an infinite re-dial loop.
2659
+ */
2660
+ declare const PHONE_SERVER_MAX_CALLBACK_CHAIN = 3;
2661
+ /** Default callback envelope when the caller doesn't set one. */
2662
+ declare const DEFAULT_CALLBACK_POLICY: PhoneCallbackPolicy;
2663
+ /**
2664
+ * Floor + ceiling on how far into the future a `schedule_callback` may
2665
+ * defer. Lower bound prevents instant re-dial loops (give the human a
2666
+ * breath); upper bound bounds the staging window so a scheduled
2667
+ * callback can't sit in the DB forever.
2668
+ */
2669
+ declare const PHONE_CALLBACK_MIN_DELAY_SECONDS = 30;
2670
+ declare const PHONE_CALLBACK_MAX_DELAY_SECONDS: number;
2626
2671
  interface PhoneConfirmPolicy {
2627
2672
  paymentDetails: 'never';
2628
2673
  contractCommitment: 'never';
@@ -2746,6 +2791,15 @@ type PhoneMissionStartValidationResult = {
2746
2791
  ok: false;
2747
2792
  issues: PhoneMissionValidationIssue[];
2748
2793
  };
2794
+ /**
2795
+ * Resolve the effective extension policy: caller's value (if any),
2796
+ * clamped DOWN to the server ceiling on each field. The server cap
2797
+ * always wins — a caller asking for `maxSecondsPerRequest: 999_999`
2798
+ * gets {@link PHONE_SERVER_MAX_EXTENSION_SECONDS_PER_REQUEST}.
2799
+ */
2800
+ declare function resolveExtensionPolicy(input: PhoneExtensionPolicy | undefined): PhoneExtensionPolicy;
2801
+ /** Resolve the effective callback policy with server-ceiling clamping. */
2802
+ declare function resolveCallbackPolicy(input: PhoneCallbackPolicy | undefined): PhoneCallbackPolicy;
2749
2803
  declare function validatePhoneMissionPolicy(policy: unknown): PhoneMissionValidationResult;
2750
2804
  declare function validatePhoneTransportProfile(transport: unknown): PhoneTransportValidationResult;
2751
2805
  declare function inferPhoneRegion(phoneNumber: string): PhoneRegionScope | null;
@@ -2902,6 +2956,48 @@ declare const SEARCH_SKILLS_TOOL: RealtimeToolDefinition;
2902
2956
  * oldest (the bridge enforces this).
2903
2957
  */
2904
2958
  declare const LOAD_SKILL_TOOL: RealtimeToolDefinition;
2959
+ /**
2960
+ * v0.9.81 — time-budget self-awareness. The voice model on a live call
2961
+ * needs to know HOW LONG IT HAS, get reminded as that window closes,
2962
+ * and have a graceful exit when it runs out. This tool returns a
2963
+ * snapshot the model can read at any point. Cheap: pure function over
2964
+ * bridge state, returns in microseconds.
2965
+ */
2966
+ declare const GET_CALL_STATUS_TOOL: RealtimeToolDefinition;
2967
+ /**
2968
+ * v0.9.81 — ask for more time on the current call. Auto-approved up to
2969
+ * the per-call extension policy (per-request cap, per-call request cap,
2970
+ * total seconds cap). On partial / refused grants the message field
2971
+ * explains exactly what the agent has left so it can adapt rather than
2972
+ * retry-loop.
2973
+ */
2974
+ declare const EXTEND_CALL_TIME_TOOL: RealtimeToolDefinition;
2975
+ /**
2976
+ * v0.9.81 — arrange an automatic callback when you cannot finish in
2977
+ * this session (time, context, conversation needs a break, etc.). The
2978
+ * bridge captures the agent's summary + a transcript digest now; the
2979
+ * scheduler dials back at `delaySeconds` with full context loaded into
2980
+ * the next call's task. Each call can schedule AT MOST ONE callback,
2981
+ * and only within the mission's callbackPolicy.
2982
+ */
2983
+ declare const SCHEDULE_CALLBACK_TOOL: RealtimeToolDefinition;
2984
+ /**
2985
+ * v0.9.82 — the hang-up tool the agent must call when it's done.
2986
+ *
2987
+ * Before v0.9.82 the realtime voice model could SAY "Goodbye, I'll
2988
+ * hang up now" but had no way to actually drop the call — the bridge
2989
+ * only ended on a carrier-side bye (human hung up), OpenAI socket
2990
+ * close, time-budget grace expiry, or programmatic teardown from the
2991
+ * API layer. So the agent would say goodbye and then sit silently
2992
+ * waiting for the human to hang up, racking up minutes.
2993
+ *
2994
+ * end_call wires the model to {@link RealtimeVoiceBridge.endByAgentRequest}
2995
+ * which sends the carrier its end-of-call frame and closes both
2996
+ * sockets. The model is instructed (in {@link buildRealtimeToolGuidance})
2997
+ * to ALWAYS call this after it has said goodbye — verbal acknowledgement
2998
+ * is not enough.
2999
+ */
3000
+ declare const END_CALL_TOOL: RealtimeToolDefinition;
2905
3001
  /** Every tool defined in this module, keyed by name. */
2906
3002
  declare const REALTIME_TOOL_DEFINITIONS: Record<string, RealtimeToolDefinition>;
2907
3003
  /**
@@ -3821,6 +3917,38 @@ interface PhoneWebhookResult {
3821
3917
  mission: PhoneCallMission;
3822
3918
  action: Record<string, unknown>;
3823
3919
  }
3920
+ /**
3921
+ * Persisted shape of a `schedule_callback` request. Stored verbatim
3922
+ * on `mission.metadata.scheduledCallback`; the scheduler reads it back
3923
+ * when the wall-clock reaches `at`.
3924
+ *
3925
+ * - `at` — when to dial back, ISO timestamp
3926
+ * - `reason` — short audit string
3927
+ * - `agentSummary` — what the next call needs to know (model-provided)
3928
+ * - `transcriptDigest` — bridge-built rolling transcript snapshot
3929
+ * - `chainDepth` — 0 for first scheduled callback, 1 if THIS mission
3930
+ * was itself a callback, 2 if its parent was too, …
3931
+ * Used to enforce `policy.callbackPolicy.maxCallbackChain`
3932
+ * without re-walking the chain at dial time.
3933
+ * - `status` — pending → dialing → fired (mission spawned) | failed
3934
+ * - `callbackMissionId` — id of the new mission once dialing happens
3935
+ * - `armedAt` — when this record was written, audit only
3936
+ * - `firedAt` — when the scheduler actually dialed
3937
+ * - `lastError` — last dial-failure message (the scheduler retries
3938
+ * inside the manager; this is the visibility hook)
3939
+ */
3940
+ interface PhoneScheduledCallback {
3941
+ at: string;
3942
+ reason: string;
3943
+ agentSummary: string;
3944
+ transcriptDigest: string;
3945
+ chainDepth: number;
3946
+ status: 'pending' | 'dialing' | 'fired' | 'failed';
3947
+ callbackMissionId?: string;
3948
+ armedAt: string;
3949
+ firedAt?: string;
3950
+ lastError?: string;
3951
+ }
3824
3952
  declare function redactPhoneTransportConfig(config: PhoneTransportConfig): PhoneTransportConfig;
3825
3953
  declare class PhoneManager {
3826
3954
  private db;
@@ -4815,6 +4943,18 @@ declare class ServiceManager {
4815
4943
 
4816
4944
  interface SetupConfig {
4817
4945
  masterKey: string;
4946
+ /**
4947
+ * Shared secret the inbound-email webhook authenticates against
4948
+ * (`X-Inbound-Secret` header). Auto-minted at setup time and
4949
+ * persisted alongside `masterKey` so every API restart reuses the
4950
+ * same value — without this, the API generated a fresh secret on
4951
+ * every cold start and printed a noisy warning to the operator.
4952
+ *
4953
+ * Optional in the type for backward compatibility with existing
4954
+ * on-disk configs; {@link SetupManager.initConfig} lazy-mints it
4955
+ * into older configs the first time it loads them.
4956
+ */
4957
+ inboundSecret?: string;
4818
4958
  stalwart: {
4819
4959
  url: string;
4820
4960
  adminUser: string;
@@ -4876,6 +5016,13 @@ declare class SetupManager {
4876
5016
  * Always regenerates Docker files to keep passwords in sync.
4877
5017
  */
4878
5018
  initConfig(): SetupResult;
5019
+ /**
5020
+ * Append `AGENTICMAIL_INBOUND_SECRET=...` to .env if the file does
5021
+ * not already contain that key. Used by the lazy-mint path to make
5022
+ * sure existing installs pick up the new secret on next boot
5023
+ * without clobbering anything the operator added.
5024
+ */
5025
+ private ensureEnvHasInboundSecret;
4879
5026
  /**
4880
5027
  * Generate docker-compose.yml and stalwart.toml in ~/.agenticmail/
4881
5028
  * with the correct admin password from config.
@@ -5968,4 +6115,4 @@ declare function userSkillsDir(): string;
5968
6115
  */
5969
6116
  declare function renderSkillAsPrompt(skill: Skill): string;
5970
6117
 
5971
- export { AGENT_ROLES, ASK_OPERATOR_TOOL, 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, type AudioAction, type AudioEditOptions, 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_REALTIME_AUDIO_FORMAT, DEFAULT_REALTIME_MODEL, DEFAULT_REALTIME_VOICE, DEFAULT_SESSION_MAX_AGE_MS, DEFAULT_WEB_SEARCH_ENDPOINT, 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, ELKS_REALTIME_WS_PATH, type ElksRealtimeAudioFormat, type ElksRealtimeAudioMessage, type ElksRealtimeByeMessage, type ElksRealtimeHelloMessage, type ElksRealtimeInboundMessage, type ElksRealtimeOutboundMessage, ElksRealtimeTransport, type EmailEnvelope, type EmailRouteAction, type EmailRouteClass, type EmailRouteClassification, type EmailRouteInput, EmailSearchIndex, type FolderInfo, GET_DATETIME_TOOL, type GatewayConfig, GatewayManager, type GatewayManagerOptions, type GatewayMode, type GatewayStatus, type GetDatetimeOptions, type GetUpdatesOptions, type HostName, type HostSession, type HostSessionResumeMode, type ImageAction, type ImageEditOptions, type InboundEmail, type InboundSmsEvent, type InboxEvent, type InboxExpungeEvent, type InboxFlagsEvent, type InboxNewEvent, InboxWatcher, type InboxWatcherOptions, type InstallProgress, LOAD_SKILL_TOOL, type LinkAdvisory, type LocalSmtpConfig, MEMORY_CATEGORIES, MailReceiver, type MailReceiverOptions, MailSender, type MailSenderOptions, type MailboxInfo, type MediaBinary, type MediaCapability, type MediaCapabilityReport, type MediaFileResult, type MediaInfoResult, MediaManager, type MediaManagerOptions, type MediaStreamInfo, type MemoryCategory, type MemoryImportance, type MemoryQueryOptions, type MemoryRecaller, MemorySearchIndex, type MemorySource, type MemoryStats, OPENAI_REALTIME_URL, OPERATOR_QUERY_POLL_INTERVAL_MS, OPERATOR_QUERY_SUBJECT_TAG, OPERATOR_QUERY_TIMEOUT_MS, OPERATOR_QUERY_TIMEOUT_SENTINEL, type OpenClawPhoneMissionPolicy, type OperatorQueryNotificationInput, type OperatorQueryPollOptions, type OperatorQueryUrgency, type OperatorReplyKind, type OutboundCategory, type OutboundScanInput, type OutboundScanResult, type OutboundWarning, PHONE_CALL_CONTROL_PROVIDERS, 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 ParsedOperatorReply, type ParsedSms, type ParsedTelegramMessage, PathTraversalError, type PhoneAlternativePolicy, type PhoneCallMission, type PhoneConfirmPolicy, PhoneManager, type PhoneMissionStartValidationResult, type PhoneMissionState, type PhoneMissionTranscriptEntry, type PhoneMissionValidationIssue, type PhoneMissionValidationResult, type PhoneNumberRisk, type PhoneOperatorQuery, PhoneRateLimitError, type PhoneRegionScope, type PhoneTransportConfig, type PhoneTransportProfile, type PhoneTransportProvider, type PhoneTransportValidationResult, PhoneWebhookAuthError, type PhoneWebhookResult, type PlanBridgeWakeArgs, type PurchasedDomain, REALTIME_AUDIO_SAMPLE_RATE, REALTIME_MAX_AUDIO_FRAME_BASE64, REALTIME_TOOL_CALL_TIMEOUT_MS, REALTIME_TOOL_DEFINITIONS, RECALL_MEMORY_TOOL, REDACTED, RELAY_PRESETS, type RealtimeBridgePort, type RealtimeBridgeTranscriptEntry, type RealtimeInboundEvent, type RealtimeInstructionOptions, type RealtimeSessionConfigOptions, type RealtimeToolCall, type RealtimeToolDefinition, type RealtimeToolHandler, type RealtimeToolResult, type RealtimeTransportAdapter, type RealtimeTransportProvider, RealtimeVoiceBridge, type RealtimeVoiceBridgeOptions, RelayBridge, type RelayBridgeOptions, type RelayConfig, RelayGateway, type RelayProvider, type RelaySearchResult, type ResumeErrorClassificationOptions, SEARCH_EMAIL_TOOL, SEARCH_SKILLS_TOOL, SPAM_THRESHOLD, type SafeJoinOptions, type SanitizeDetection, type SanitizeResult, type SearchCriteria, type SearchableEmail, type SecurityAdvisory, type SendMailOptions, type SendResult, type SendResultWithRaw, type SendSmsInput, type SendSmsResult, type SendTelegramMessageOptions, type SendTelegramMessageResult, ServiceManager, type ServiceStatus, type SetWebhookOptions, type SetupConfig, SetupManager, type SetupResult, type Severity, type Skill, type SkillCategory, type SkillContext, type SkillExitStrategy, type SkillSummary, type SkillTactic, type SkillValidationError, 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, TELEGRAM_API_BASE, TELEGRAM_CHUNK_SIZE, TELEGRAM_MESSAGE_LIMIT, TELEGRAM_MIN_WEBHOOK_SECRET_LENGTH, TELEGRAM_OPERATOR_QUERY_TAG, TELEGRAM_STOP_WORDS, TELEGRAM_WEBHOOK_SECRET_RE, TELEPHONY_TRANSPORT_CAPABILITIES, TWILIO_MEDIA_SAMPLE_RATE, TWILIO_REALTIME_WS_PATH, TelegramApiError, type TelegramApiOptions, type TelegramBotInfo, type TelegramChatType, type TelegramConfig, TelegramManager, type TelegramMessage, type TelegramMode, type TelephonyTransportCapability, ThreadCache, type ThreadCacheEntry, type ThreadCacheOptions, type ThreadIdInput, type ToolExecutor, type TtsGenerateOptions, type TunnelConfig, TunnelManager, type TwilioConnectedMessage, type TwilioMarkMessage, type TwilioMediaMessage, type TwilioRealtimeInboundMessage, type TwilioRealtimeOutboundMessage, TwilioRealtimeTransport, type TwilioStartMessage, type TwilioStopMessage, type TwilioStreamTwiMLOptions, UnsafeApiUrlError, type UpdateMemoryInput, type ValidatedPhoneMissionStart, type VideoAction, type VideoEditOptions, type VideoTimelineEntry, type VideoUnderstandOptions, type VideoUnderstandResult, type VoiceCloneOptions, WARNING_THRESHOLD, WEB_SEARCH_TOOL, WEB_SEARCH_UNTRUSTED_PREFIX, type WatcherOptions, type WebSearchOptions, assertWithinBase, bridgeWakeErrorMessage, bridgeWakeLastSeenAgeMs, buildApiUrl, buildElksAudioMessage, buildElksByeMessage, buildElksHandshakeMessages, buildElksInterruptMessage, buildElksListeningMessage, buildElksSendingMessage, buildInboundSecurityAdvisory, buildOpenAIRealtimeUrl, buildPhoneTransportConfig, buildRealtimeInstructions, buildRealtimeSessionConfig, buildRealtimeToolGuidance, buildTwilioClearMessage, buildTwilioMarkMessage, buildTwilioMediaMessage, buildTwilioSayTwiML, buildTwilioSignature, buildTwilioStreamTwiML, callTelegramApi, classifyEmailRoute, classifyPhoneNumberRisk, classifyResumeError, clearMediaCapabilityCache, closeDatabase, composeBridgeWakePrompt, createRealtimeTransport, createTestDatabase, createToolExecutor, debug, debugWarn, deleteTelegramWebhook, detectBinary, ensureDataDir, escapeXml, extractEmailAddress, extractVerificationCode, flushTelemetry, forgetHostSession, formatOperatorQueryTelegramMessage, getDatabase, getDatetime, getMediaCapabilities, getOperatorEmail, getSmsProvider, getTelegramChat, getTelegramMe, getTelegramUpdates, getTelegramWebhookInfo, hostSessionStoragePath, inferPhoneRegion, invalidateSkillCache, isInternalEmail, isLoopbackMailHost, isOperatorReplySender, isPhoneRegionAllowed, isSessionFresh, isTelegramChatAllowed, isTelegramStopCommand, isValidPhoneNumber, listSkills, loadHostSession, loadSkill, mapProviderSmsStatus, nextTelegramOffset, normalizeAddress, normalizePhoneNumber, normalizeSubject, operatorPrefsStoragePath, operatorQuerySubject, parseElksRealtimeMessage, parseEmail, parseGoogleVoiceSms, parseOperatorQueryReply, parseTelegramOperatorReply, parseTelegramUpdate, parseTwilioRealtimeMessage, planBridgeWake, pollForOperatorAnswer, recallMemory, recordToolCall, redactBotToken, redactObject, redactPhoneTransportConfig, redactSecret, redactSmsConfig, redactTelegramConfig, renderSkillAsPrompt, requireBinary, requireWhisperModel, resolveConfig, resolveTlsRejectUnauthorized, safeJoin, sanitizeEmail, saveConfig, saveHostSession, saveUserSkill, scanOutboundEmail, scoreEmail, searchSkills, sendTelegramMessage, setOperatorEmail, setTelegramWebhook, setTelemetryVersion, shouldSkipBridgeWakeForLiveOperator, splitTelegramMessage, startRelayBridge, stem, stripTelegramMarkdown, threadIdFor, tokenize, tryJoin, userSkillsDir, validateApiUrl, validatePhoneMissionPolicy, validatePhoneMissionStart, validatePhoneTransportProfile, validateSkill, validateTwilioSignature, webSearch };
6118
+ export { AGENT_ROLES, ASK_OPERATOR_TOOL, 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, type AudioAction, type AudioEditOptions, 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_CALLBACK_POLICY, DEFAULT_EXTENSION_POLICY, DEFAULT_REALTIME_AUDIO_FORMAT, DEFAULT_REALTIME_MODEL, DEFAULT_REALTIME_VOICE, DEFAULT_SESSION_MAX_AGE_MS, DEFAULT_WEB_SEARCH_ENDPOINT, 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, ELKS_REALTIME_WS_PATH, END_CALL_TOOL, EXTEND_CALL_TIME_TOOL, type ElksRealtimeAudioFormat, type ElksRealtimeAudioMessage, type ElksRealtimeByeMessage, type ElksRealtimeHelloMessage, type ElksRealtimeInboundMessage, type ElksRealtimeOutboundMessage, ElksRealtimeTransport, type EmailEnvelope, type EmailRouteAction, type EmailRouteClass, type EmailRouteClassification, type EmailRouteInput, EmailSearchIndex, type FolderInfo, GET_CALL_STATUS_TOOL, GET_DATETIME_TOOL, type GatewayConfig, GatewayManager, type GatewayManagerOptions, type GatewayMode, type GatewayStatus, type GetDatetimeOptions, type GetUpdatesOptions, type HostName, type HostSession, type HostSessionResumeMode, type ImageAction, type ImageEditOptions, type InboundEmail, type InboundSmsEvent, type InboxEvent, type InboxExpungeEvent, type InboxFlagsEvent, type InboxNewEvent, InboxWatcher, type InboxWatcherOptions, type InstallProgress, LOAD_SKILL_TOOL, type LinkAdvisory, type LocalSmtpConfig, MEMORY_CATEGORIES, MailReceiver, type MailReceiverOptions, MailSender, type MailSenderOptions, type MailboxInfo, type MediaBinary, type MediaCapability, type MediaCapabilityReport, type MediaFileResult, type MediaInfoResult, MediaManager, type MediaManagerOptions, type MediaStreamInfo, type MemoryCategory, type MemoryImportance, type MemoryQueryOptions, type MemoryRecaller, MemorySearchIndex, type MemorySource, type MemoryStats, OPENAI_REALTIME_URL, OPERATOR_QUERY_POLL_INTERVAL_MS, OPERATOR_QUERY_SUBJECT_TAG, OPERATOR_QUERY_TIMEOUT_MS, OPERATOR_QUERY_TIMEOUT_SENTINEL, type OpenClawPhoneMissionPolicy, type OperatorQueryNotificationInput, type OperatorQueryPollOptions, type OperatorQueryUrgency, type OperatorReplyKind, type OutboundCategory, type OutboundScanInput, type OutboundScanResult, type OutboundWarning, PHONE_CALLBACK_MAX_DELAY_SECONDS, PHONE_CALLBACK_MIN_DELAY_SECONDS, PHONE_CALL_CONTROL_PROVIDERS, 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_CALLBACK_CHAIN, PHONE_SERVER_MAX_CALL_DURATION_SECONDS, PHONE_SERVER_MAX_COST_PER_MISSION, PHONE_SERVER_MAX_EXTENSION_REQUESTS_PER_CALL, PHONE_SERVER_MAX_EXTENSION_SECONDS_PER_REQUEST, PHONE_SERVER_MAX_TOTAL_EXTENSION_SECONDS, PHONE_TASK_MAX_LENGTH, type ParsedAttachment, type ParsedEmail, type ParsedOperatorReply, type ParsedSms, type ParsedTelegramMessage, PathTraversalError, type PhoneAlternativePolicy, type PhoneCallMission, type PhoneCallbackPolicy, type PhoneConfirmPolicy, type PhoneExtensionPolicy, PhoneManager, type PhoneMissionStartValidationResult, type PhoneMissionState, type PhoneMissionTranscriptEntry, type PhoneMissionValidationIssue, type PhoneMissionValidationResult, type PhoneNumberRisk, type PhoneOperatorQuery, PhoneRateLimitError, type PhoneRegionScope, type PhoneScheduledCallback, type PhoneTransportConfig, type PhoneTransportProfile, type PhoneTransportProvider, type PhoneTransportValidationResult, PhoneWebhookAuthError, type PhoneWebhookResult, type PlanBridgeWakeArgs, type PurchasedDomain, REALTIME_AUDIO_SAMPLE_RATE, REALTIME_MAX_AUDIO_FRAME_BASE64, REALTIME_TOOL_CALL_TIMEOUT_MS, REALTIME_TOOL_DEFINITIONS, RECALL_MEMORY_TOOL, REDACTED, RELAY_PRESETS, type RealtimeBridgePort, type RealtimeBridgeTranscriptEntry, type RealtimeInboundEvent, type RealtimeInstructionOptions, type RealtimeSessionConfigOptions, type RealtimeToolCall, type RealtimeToolDefinition, type RealtimeToolHandler, type RealtimeToolResult, type RealtimeTransportAdapter, type RealtimeTransportProvider, RealtimeVoiceBridge, type RealtimeVoiceBridgeOptions, RelayBridge, type RelayBridgeOptions, type RelayConfig, RelayGateway, type RelayProvider, type RelaySearchResult, type ResumeErrorClassificationOptions, SCHEDULE_CALLBACK_TOOL, SEARCH_EMAIL_TOOL, SEARCH_SKILLS_TOOL, SPAM_THRESHOLD, type SafeJoinOptions, type SanitizeDetection, type SanitizeResult, type ScheduledCallbackRequest, type SearchCriteria, type SearchableEmail, type SecurityAdvisory, type SendMailOptions, type SendResult, type SendResultWithRaw, type SendSmsInput, type SendSmsResult, type SendTelegramMessageOptions, type SendTelegramMessageResult, ServiceManager, type ServiceStatus, type SetWebhookOptions, type SetupConfig, SetupManager, type SetupResult, type Severity, type Skill, type SkillCategory, type SkillContext, type SkillExitStrategy, type SkillSummary, type SkillTactic, type SkillValidationError, 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, TELEGRAM_API_BASE, TELEGRAM_CHUNK_SIZE, TELEGRAM_MESSAGE_LIMIT, TELEGRAM_MIN_WEBHOOK_SECRET_LENGTH, TELEGRAM_OPERATOR_QUERY_TAG, TELEGRAM_STOP_WORDS, TELEGRAM_WEBHOOK_SECRET_RE, TELEPHONY_TRANSPORT_CAPABILITIES, TWILIO_MEDIA_SAMPLE_RATE, TWILIO_REALTIME_WS_PATH, TelegramApiError, type TelegramApiOptions, type TelegramBotInfo, type TelegramChatType, type TelegramConfig, TelegramManager, type TelegramMessage, type TelegramMode, type TelephonyTransportCapability, ThreadCache, type ThreadCacheEntry, type ThreadCacheOptions, type ThreadIdInput, type ToolExecutor, type TtsGenerateOptions, type TunnelConfig, TunnelManager, type TwilioConnectedMessage, type TwilioMarkMessage, type TwilioMediaMessage, type TwilioRealtimeInboundMessage, type TwilioRealtimeOutboundMessage, TwilioRealtimeTransport, type TwilioStartMessage, type TwilioStopMessage, type TwilioStreamTwiMLOptions, UnsafeApiUrlError, type UpdateMemoryInput, type ValidatedPhoneMissionStart, type VideoAction, type VideoEditOptions, type VideoTimelineEntry, type VideoUnderstandOptions, type VideoUnderstandResult, type VoiceCloneOptions, WARNING_THRESHOLD, WEB_SEARCH_TOOL, WEB_SEARCH_UNTRUSTED_PREFIX, type WatcherOptions, type WebSearchOptions, assertWithinBase, bridgeWakeErrorMessage, bridgeWakeLastSeenAgeMs, buildApiUrl, buildElksAudioMessage, buildElksByeMessage, buildElksHandshakeMessages, buildElksInterruptMessage, buildElksListeningMessage, buildElksSendingMessage, buildInboundSecurityAdvisory, buildOpenAIRealtimeUrl, buildPhoneTransportConfig, buildRealtimeInstructions, buildRealtimeSessionConfig, buildRealtimeToolGuidance, buildTwilioClearMessage, buildTwilioMarkMessage, buildTwilioMediaMessage, buildTwilioSayTwiML, buildTwilioSignature, buildTwilioStreamTwiML, callTelegramApi, classifyEmailRoute, classifyPhoneNumberRisk, classifyResumeError, clearMediaCapabilityCache, closeDatabase, composeBridgeWakePrompt, createRealtimeTransport, createTestDatabase, createToolExecutor, debug, debugWarn, deleteTelegramWebhook, detectBinary, ensureDataDir, escapeXml, extractEmailAddress, extractVerificationCode, flushTelemetry, forgetHostSession, formatOperatorQueryTelegramMessage, getDatabase, getDatetime, getMediaCapabilities, getOperatorEmail, getSmsProvider, getTelegramChat, getTelegramMe, getTelegramUpdates, getTelegramWebhookInfo, hostSessionStoragePath, inferPhoneRegion, invalidateSkillCache, isInternalEmail, isLoopbackMailHost, isOperatorReplySender, isPhoneRegionAllowed, isSessionFresh, isTelegramChatAllowed, isTelegramStopCommand, isValidPhoneNumber, listSkills, loadHostSession, loadSkill, mapProviderSmsStatus, nextTelegramOffset, normalizeAddress, normalizePhoneNumber, normalizeSubject, operatorPrefsStoragePath, operatorQuerySubject, parseElksRealtimeMessage, parseEmail, parseGoogleVoiceSms, parseOperatorQueryReply, parseTelegramOperatorReply, parseTelegramUpdate, parseTwilioRealtimeMessage, planBridgeWake, pollForOperatorAnswer, recallMemory, recordToolCall, redactBotToken, redactObject, redactPhoneTransportConfig, redactSecret, redactSmsConfig, redactTelegramConfig, renderSkillAsPrompt, requireBinary, requireWhisperModel, resolveCallbackPolicy, resolveConfig, resolveExtensionPolicy, resolveTlsRejectUnauthorized, safeJoin, sanitizeEmail, saveConfig, saveHostSession, saveUserSkill, scanOutboundEmail, scoreEmail, searchSkills, sendTelegramMessage, setOperatorEmail, setTelegramWebhook, setTelemetryVersion, shouldSkipBridgeWakeForLiveOperator, splitTelegramMessage, startRelayBridge, stem, stripTelegramMarkdown, threadIdFor, tokenize, tryJoin, userSkillsDir, validateApiUrl, validatePhoneMissionPolicy, validatePhoneMissionStart, validatePhoneTransportProfile, validateSkill, validateTwilioSignature, webSearch };
package/dist/index.d.ts CHANGED
@@ -2623,6 +2623,51 @@ declare const PHONE_SERVER_MAX_COST_PER_MISSION = 5;
2623
2623
  declare const PHONE_SERVER_MAX_ATTEMPTS = 3;
2624
2624
  /** Hard cap on the free-text `task` fed to the voice runtime. */
2625
2625
  declare const PHONE_TASK_MAX_LENGTH = 2000;
2626
+ /**
2627
+ * Server-side ceilings for the extension policy. Like the duration /
2628
+ * cost caps above, these are the financial blast-radius bound — a
2629
+ * caller can ask for a stricter extension policy but never a looser
2630
+ * one. The defaults err on the side of "give the agent a fighting
2631
+ * chance to finish a real call" without letting it sit on the line
2632
+ * forever. v0.9.82 bumped these substantially after field reports of
2633
+ * agents running out of time on legitimately long calls (15-25 min
2634
+ * hold queues, 30 min explanations from the rep):
2635
+ *
2636
+ * - per-request cap raised 5 min → 15 min so a single "I need more
2637
+ * time on hold" request can carry the agent through a queue
2638
+ * - per-call cap raised 4 → 8 so chained extensions don't run dry
2639
+ * on a long bureaucracy call
2640
+ * - total cap raised 10 min → 1 hour so the absolute add can match
2641
+ * a long-tail call without artificial chunking
2642
+ *
2643
+ * The TOTAL also can't push the call past
2644
+ * PHONE_SERVER_MAX_CALL_DURATION_SECONDS — that ceiling still wins.
2645
+ */
2646
+ declare const PHONE_SERVER_MAX_EXTENSION_SECONDS_PER_REQUEST = 900;
2647
+ declare const PHONE_SERVER_MAX_EXTENSION_REQUESTS_PER_CALL = 8;
2648
+ declare const PHONE_SERVER_MAX_TOTAL_EXTENSION_SECONDS = 3600;
2649
+ /** Default per-call extension envelope when the caller doesn't set one.
2650
+ * Bumped in v0.9.82 — 5 min × 4 = 20 min of headroom is a much more
2651
+ * realistic out-of-the-box budget for the kinds of calls operators
2652
+ * actually use this for (bills, bookings, customer support). */
2653
+ declare const DEFAULT_EXTENSION_POLICY: PhoneExtensionPolicy;
2654
+ /**
2655
+ * Server-side ceiling on how deep a callback chain can go. Each call
2656
+ * counts; a brand-new mission is depth 0, its callback is depth 1, the
2657
+ * callback's callback is depth 2. Prevents an agent + bot operator on
2658
+ * the other end from getting stuck in an infinite re-dial loop.
2659
+ */
2660
+ declare const PHONE_SERVER_MAX_CALLBACK_CHAIN = 3;
2661
+ /** Default callback envelope when the caller doesn't set one. */
2662
+ declare const DEFAULT_CALLBACK_POLICY: PhoneCallbackPolicy;
2663
+ /**
2664
+ * Floor + ceiling on how far into the future a `schedule_callback` may
2665
+ * defer. Lower bound prevents instant re-dial loops (give the human a
2666
+ * breath); upper bound bounds the staging window so a scheduled
2667
+ * callback can't sit in the DB forever.
2668
+ */
2669
+ declare const PHONE_CALLBACK_MIN_DELAY_SECONDS = 30;
2670
+ declare const PHONE_CALLBACK_MAX_DELAY_SECONDS: number;
2626
2671
  interface PhoneConfirmPolicy {
2627
2672
  paymentDetails: 'never';
2628
2673
  contractCommitment: 'never';
@@ -2746,6 +2791,15 @@ type PhoneMissionStartValidationResult = {
2746
2791
  ok: false;
2747
2792
  issues: PhoneMissionValidationIssue[];
2748
2793
  };
2794
+ /**
2795
+ * Resolve the effective extension policy: caller's value (if any),
2796
+ * clamped DOWN to the server ceiling on each field. The server cap
2797
+ * always wins — a caller asking for `maxSecondsPerRequest: 999_999`
2798
+ * gets {@link PHONE_SERVER_MAX_EXTENSION_SECONDS_PER_REQUEST}.
2799
+ */
2800
+ declare function resolveExtensionPolicy(input: PhoneExtensionPolicy | undefined): PhoneExtensionPolicy;
2801
+ /** Resolve the effective callback policy with server-ceiling clamping. */
2802
+ declare function resolveCallbackPolicy(input: PhoneCallbackPolicy | undefined): PhoneCallbackPolicy;
2749
2803
  declare function validatePhoneMissionPolicy(policy: unknown): PhoneMissionValidationResult;
2750
2804
  declare function validatePhoneTransportProfile(transport: unknown): PhoneTransportValidationResult;
2751
2805
  declare function inferPhoneRegion(phoneNumber: string): PhoneRegionScope | null;
@@ -2902,6 +2956,48 @@ declare const SEARCH_SKILLS_TOOL: RealtimeToolDefinition;
2902
2956
  * oldest (the bridge enforces this).
2903
2957
  */
2904
2958
  declare const LOAD_SKILL_TOOL: RealtimeToolDefinition;
2959
+ /**
2960
+ * v0.9.81 — time-budget self-awareness. The voice model on a live call
2961
+ * needs to know HOW LONG IT HAS, get reminded as that window closes,
2962
+ * and have a graceful exit when it runs out. This tool returns a
2963
+ * snapshot the model can read at any point. Cheap: pure function over
2964
+ * bridge state, returns in microseconds.
2965
+ */
2966
+ declare const GET_CALL_STATUS_TOOL: RealtimeToolDefinition;
2967
+ /**
2968
+ * v0.9.81 — ask for more time on the current call. Auto-approved up to
2969
+ * the per-call extension policy (per-request cap, per-call request cap,
2970
+ * total seconds cap). On partial / refused grants the message field
2971
+ * explains exactly what the agent has left so it can adapt rather than
2972
+ * retry-loop.
2973
+ */
2974
+ declare const EXTEND_CALL_TIME_TOOL: RealtimeToolDefinition;
2975
+ /**
2976
+ * v0.9.81 — arrange an automatic callback when you cannot finish in
2977
+ * this session (time, context, conversation needs a break, etc.). The
2978
+ * bridge captures the agent's summary + a transcript digest now; the
2979
+ * scheduler dials back at `delaySeconds` with full context loaded into
2980
+ * the next call's task. Each call can schedule AT MOST ONE callback,
2981
+ * and only within the mission's callbackPolicy.
2982
+ */
2983
+ declare const SCHEDULE_CALLBACK_TOOL: RealtimeToolDefinition;
2984
+ /**
2985
+ * v0.9.82 — the hang-up tool the agent must call when it's done.
2986
+ *
2987
+ * Before v0.9.82 the realtime voice model could SAY "Goodbye, I'll
2988
+ * hang up now" but had no way to actually drop the call — the bridge
2989
+ * only ended on a carrier-side bye (human hung up), OpenAI socket
2990
+ * close, time-budget grace expiry, or programmatic teardown from the
2991
+ * API layer. So the agent would say goodbye and then sit silently
2992
+ * waiting for the human to hang up, racking up minutes.
2993
+ *
2994
+ * end_call wires the model to {@link RealtimeVoiceBridge.endByAgentRequest}
2995
+ * which sends the carrier its end-of-call frame and closes both
2996
+ * sockets. The model is instructed (in {@link buildRealtimeToolGuidance})
2997
+ * to ALWAYS call this after it has said goodbye — verbal acknowledgement
2998
+ * is not enough.
2999
+ */
3000
+ declare const END_CALL_TOOL: RealtimeToolDefinition;
2905
3001
  /** Every tool defined in this module, keyed by name. */
2906
3002
  declare const REALTIME_TOOL_DEFINITIONS: Record<string, RealtimeToolDefinition>;
2907
3003
  /**
@@ -3821,6 +3917,38 @@ interface PhoneWebhookResult {
3821
3917
  mission: PhoneCallMission;
3822
3918
  action: Record<string, unknown>;
3823
3919
  }
3920
+ /**
3921
+ * Persisted shape of a `schedule_callback` request. Stored verbatim
3922
+ * on `mission.metadata.scheduledCallback`; the scheduler reads it back
3923
+ * when the wall-clock reaches `at`.
3924
+ *
3925
+ * - `at` — when to dial back, ISO timestamp
3926
+ * - `reason` — short audit string
3927
+ * - `agentSummary` — what the next call needs to know (model-provided)
3928
+ * - `transcriptDigest` — bridge-built rolling transcript snapshot
3929
+ * - `chainDepth` — 0 for first scheduled callback, 1 if THIS mission
3930
+ * was itself a callback, 2 if its parent was too, …
3931
+ * Used to enforce `policy.callbackPolicy.maxCallbackChain`
3932
+ * without re-walking the chain at dial time.
3933
+ * - `status` — pending → dialing → fired (mission spawned) | failed
3934
+ * - `callbackMissionId` — id of the new mission once dialing happens
3935
+ * - `armedAt` — when this record was written, audit only
3936
+ * - `firedAt` — when the scheduler actually dialed
3937
+ * - `lastError` — last dial-failure message (the scheduler retries
3938
+ * inside the manager; this is the visibility hook)
3939
+ */
3940
+ interface PhoneScheduledCallback {
3941
+ at: string;
3942
+ reason: string;
3943
+ agentSummary: string;
3944
+ transcriptDigest: string;
3945
+ chainDepth: number;
3946
+ status: 'pending' | 'dialing' | 'fired' | 'failed';
3947
+ callbackMissionId?: string;
3948
+ armedAt: string;
3949
+ firedAt?: string;
3950
+ lastError?: string;
3951
+ }
3824
3952
  declare function redactPhoneTransportConfig(config: PhoneTransportConfig): PhoneTransportConfig;
3825
3953
  declare class PhoneManager {
3826
3954
  private db;
@@ -4815,6 +4943,18 @@ declare class ServiceManager {
4815
4943
 
4816
4944
  interface SetupConfig {
4817
4945
  masterKey: string;
4946
+ /**
4947
+ * Shared secret the inbound-email webhook authenticates against
4948
+ * (`X-Inbound-Secret` header). Auto-minted at setup time and
4949
+ * persisted alongside `masterKey` so every API restart reuses the
4950
+ * same value — without this, the API generated a fresh secret on
4951
+ * every cold start and printed a noisy warning to the operator.
4952
+ *
4953
+ * Optional in the type for backward compatibility with existing
4954
+ * on-disk configs; {@link SetupManager.initConfig} lazy-mints it
4955
+ * into older configs the first time it loads them.
4956
+ */
4957
+ inboundSecret?: string;
4818
4958
  stalwart: {
4819
4959
  url: string;
4820
4960
  adminUser: string;
@@ -4876,6 +5016,13 @@ declare class SetupManager {
4876
5016
  * Always regenerates Docker files to keep passwords in sync.
4877
5017
  */
4878
5018
  initConfig(): SetupResult;
5019
+ /**
5020
+ * Append `AGENTICMAIL_INBOUND_SECRET=...` to .env if the file does
5021
+ * not already contain that key. Used by the lazy-mint path to make
5022
+ * sure existing installs pick up the new secret on next boot
5023
+ * without clobbering anything the operator added.
5024
+ */
5025
+ private ensureEnvHasInboundSecret;
4879
5026
  /**
4880
5027
  * Generate docker-compose.yml and stalwart.toml in ~/.agenticmail/
4881
5028
  * with the correct admin password from config.
@@ -5968,4 +6115,4 @@ declare function userSkillsDir(): string;
5968
6115
  */
5969
6116
  declare function renderSkillAsPrompt(skill: Skill): string;
5970
6117
 
5971
- export { AGENT_ROLES, ASK_OPERATOR_TOOL, 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, type AudioAction, type AudioEditOptions, 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_REALTIME_AUDIO_FORMAT, DEFAULT_REALTIME_MODEL, DEFAULT_REALTIME_VOICE, DEFAULT_SESSION_MAX_AGE_MS, DEFAULT_WEB_SEARCH_ENDPOINT, 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, ELKS_REALTIME_WS_PATH, type ElksRealtimeAudioFormat, type ElksRealtimeAudioMessage, type ElksRealtimeByeMessage, type ElksRealtimeHelloMessage, type ElksRealtimeInboundMessage, type ElksRealtimeOutboundMessage, ElksRealtimeTransport, type EmailEnvelope, type EmailRouteAction, type EmailRouteClass, type EmailRouteClassification, type EmailRouteInput, EmailSearchIndex, type FolderInfo, GET_DATETIME_TOOL, type GatewayConfig, GatewayManager, type GatewayManagerOptions, type GatewayMode, type GatewayStatus, type GetDatetimeOptions, type GetUpdatesOptions, type HostName, type HostSession, type HostSessionResumeMode, type ImageAction, type ImageEditOptions, type InboundEmail, type InboundSmsEvent, type InboxEvent, type InboxExpungeEvent, type InboxFlagsEvent, type InboxNewEvent, InboxWatcher, type InboxWatcherOptions, type InstallProgress, LOAD_SKILL_TOOL, type LinkAdvisory, type LocalSmtpConfig, MEMORY_CATEGORIES, MailReceiver, type MailReceiverOptions, MailSender, type MailSenderOptions, type MailboxInfo, type MediaBinary, type MediaCapability, type MediaCapabilityReport, type MediaFileResult, type MediaInfoResult, MediaManager, type MediaManagerOptions, type MediaStreamInfo, type MemoryCategory, type MemoryImportance, type MemoryQueryOptions, type MemoryRecaller, MemorySearchIndex, type MemorySource, type MemoryStats, OPENAI_REALTIME_URL, OPERATOR_QUERY_POLL_INTERVAL_MS, OPERATOR_QUERY_SUBJECT_TAG, OPERATOR_QUERY_TIMEOUT_MS, OPERATOR_QUERY_TIMEOUT_SENTINEL, type OpenClawPhoneMissionPolicy, type OperatorQueryNotificationInput, type OperatorQueryPollOptions, type OperatorQueryUrgency, type OperatorReplyKind, type OutboundCategory, type OutboundScanInput, type OutboundScanResult, type OutboundWarning, PHONE_CALL_CONTROL_PROVIDERS, 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 ParsedOperatorReply, type ParsedSms, type ParsedTelegramMessage, PathTraversalError, type PhoneAlternativePolicy, type PhoneCallMission, type PhoneConfirmPolicy, PhoneManager, type PhoneMissionStartValidationResult, type PhoneMissionState, type PhoneMissionTranscriptEntry, type PhoneMissionValidationIssue, type PhoneMissionValidationResult, type PhoneNumberRisk, type PhoneOperatorQuery, PhoneRateLimitError, type PhoneRegionScope, type PhoneTransportConfig, type PhoneTransportProfile, type PhoneTransportProvider, type PhoneTransportValidationResult, PhoneWebhookAuthError, type PhoneWebhookResult, type PlanBridgeWakeArgs, type PurchasedDomain, REALTIME_AUDIO_SAMPLE_RATE, REALTIME_MAX_AUDIO_FRAME_BASE64, REALTIME_TOOL_CALL_TIMEOUT_MS, REALTIME_TOOL_DEFINITIONS, RECALL_MEMORY_TOOL, REDACTED, RELAY_PRESETS, type RealtimeBridgePort, type RealtimeBridgeTranscriptEntry, type RealtimeInboundEvent, type RealtimeInstructionOptions, type RealtimeSessionConfigOptions, type RealtimeToolCall, type RealtimeToolDefinition, type RealtimeToolHandler, type RealtimeToolResult, type RealtimeTransportAdapter, type RealtimeTransportProvider, RealtimeVoiceBridge, type RealtimeVoiceBridgeOptions, RelayBridge, type RelayBridgeOptions, type RelayConfig, RelayGateway, type RelayProvider, type RelaySearchResult, type ResumeErrorClassificationOptions, SEARCH_EMAIL_TOOL, SEARCH_SKILLS_TOOL, SPAM_THRESHOLD, type SafeJoinOptions, type SanitizeDetection, type SanitizeResult, type SearchCriteria, type SearchableEmail, type SecurityAdvisory, type SendMailOptions, type SendResult, type SendResultWithRaw, type SendSmsInput, type SendSmsResult, type SendTelegramMessageOptions, type SendTelegramMessageResult, ServiceManager, type ServiceStatus, type SetWebhookOptions, type SetupConfig, SetupManager, type SetupResult, type Severity, type Skill, type SkillCategory, type SkillContext, type SkillExitStrategy, type SkillSummary, type SkillTactic, type SkillValidationError, 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, TELEGRAM_API_BASE, TELEGRAM_CHUNK_SIZE, TELEGRAM_MESSAGE_LIMIT, TELEGRAM_MIN_WEBHOOK_SECRET_LENGTH, TELEGRAM_OPERATOR_QUERY_TAG, TELEGRAM_STOP_WORDS, TELEGRAM_WEBHOOK_SECRET_RE, TELEPHONY_TRANSPORT_CAPABILITIES, TWILIO_MEDIA_SAMPLE_RATE, TWILIO_REALTIME_WS_PATH, TelegramApiError, type TelegramApiOptions, type TelegramBotInfo, type TelegramChatType, type TelegramConfig, TelegramManager, type TelegramMessage, type TelegramMode, type TelephonyTransportCapability, ThreadCache, type ThreadCacheEntry, type ThreadCacheOptions, type ThreadIdInput, type ToolExecutor, type TtsGenerateOptions, type TunnelConfig, TunnelManager, type TwilioConnectedMessage, type TwilioMarkMessage, type TwilioMediaMessage, type TwilioRealtimeInboundMessage, type TwilioRealtimeOutboundMessage, TwilioRealtimeTransport, type TwilioStartMessage, type TwilioStopMessage, type TwilioStreamTwiMLOptions, UnsafeApiUrlError, type UpdateMemoryInput, type ValidatedPhoneMissionStart, type VideoAction, type VideoEditOptions, type VideoTimelineEntry, type VideoUnderstandOptions, type VideoUnderstandResult, type VoiceCloneOptions, WARNING_THRESHOLD, WEB_SEARCH_TOOL, WEB_SEARCH_UNTRUSTED_PREFIX, type WatcherOptions, type WebSearchOptions, assertWithinBase, bridgeWakeErrorMessage, bridgeWakeLastSeenAgeMs, buildApiUrl, buildElksAudioMessage, buildElksByeMessage, buildElksHandshakeMessages, buildElksInterruptMessage, buildElksListeningMessage, buildElksSendingMessage, buildInboundSecurityAdvisory, buildOpenAIRealtimeUrl, buildPhoneTransportConfig, buildRealtimeInstructions, buildRealtimeSessionConfig, buildRealtimeToolGuidance, buildTwilioClearMessage, buildTwilioMarkMessage, buildTwilioMediaMessage, buildTwilioSayTwiML, buildTwilioSignature, buildTwilioStreamTwiML, callTelegramApi, classifyEmailRoute, classifyPhoneNumberRisk, classifyResumeError, clearMediaCapabilityCache, closeDatabase, composeBridgeWakePrompt, createRealtimeTransport, createTestDatabase, createToolExecutor, debug, debugWarn, deleteTelegramWebhook, detectBinary, ensureDataDir, escapeXml, extractEmailAddress, extractVerificationCode, flushTelemetry, forgetHostSession, formatOperatorQueryTelegramMessage, getDatabase, getDatetime, getMediaCapabilities, getOperatorEmail, getSmsProvider, getTelegramChat, getTelegramMe, getTelegramUpdates, getTelegramWebhookInfo, hostSessionStoragePath, inferPhoneRegion, invalidateSkillCache, isInternalEmail, isLoopbackMailHost, isOperatorReplySender, isPhoneRegionAllowed, isSessionFresh, isTelegramChatAllowed, isTelegramStopCommand, isValidPhoneNumber, listSkills, loadHostSession, loadSkill, mapProviderSmsStatus, nextTelegramOffset, normalizeAddress, normalizePhoneNumber, normalizeSubject, operatorPrefsStoragePath, operatorQuerySubject, parseElksRealtimeMessage, parseEmail, parseGoogleVoiceSms, parseOperatorQueryReply, parseTelegramOperatorReply, parseTelegramUpdate, parseTwilioRealtimeMessage, planBridgeWake, pollForOperatorAnswer, recallMemory, recordToolCall, redactBotToken, redactObject, redactPhoneTransportConfig, redactSecret, redactSmsConfig, redactTelegramConfig, renderSkillAsPrompt, requireBinary, requireWhisperModel, resolveConfig, resolveTlsRejectUnauthorized, safeJoin, sanitizeEmail, saveConfig, saveHostSession, saveUserSkill, scanOutboundEmail, scoreEmail, searchSkills, sendTelegramMessage, setOperatorEmail, setTelegramWebhook, setTelemetryVersion, shouldSkipBridgeWakeForLiveOperator, splitTelegramMessage, startRelayBridge, stem, stripTelegramMarkdown, threadIdFor, tokenize, tryJoin, userSkillsDir, validateApiUrl, validatePhoneMissionPolicy, validatePhoneMissionStart, validatePhoneTransportProfile, validateSkill, validateTwilioSignature, webSearch };
6118
+ export { AGENT_ROLES, ASK_OPERATOR_TOOL, 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, type AudioAction, type AudioEditOptions, 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_CALLBACK_POLICY, DEFAULT_EXTENSION_POLICY, DEFAULT_REALTIME_AUDIO_FORMAT, DEFAULT_REALTIME_MODEL, DEFAULT_REALTIME_VOICE, DEFAULT_SESSION_MAX_AGE_MS, DEFAULT_WEB_SEARCH_ENDPOINT, 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, ELKS_REALTIME_WS_PATH, END_CALL_TOOL, EXTEND_CALL_TIME_TOOL, type ElksRealtimeAudioFormat, type ElksRealtimeAudioMessage, type ElksRealtimeByeMessage, type ElksRealtimeHelloMessage, type ElksRealtimeInboundMessage, type ElksRealtimeOutboundMessage, ElksRealtimeTransport, type EmailEnvelope, type EmailRouteAction, type EmailRouteClass, type EmailRouteClassification, type EmailRouteInput, EmailSearchIndex, type FolderInfo, GET_CALL_STATUS_TOOL, GET_DATETIME_TOOL, type GatewayConfig, GatewayManager, type GatewayManagerOptions, type GatewayMode, type GatewayStatus, type GetDatetimeOptions, type GetUpdatesOptions, type HostName, type HostSession, type HostSessionResumeMode, type ImageAction, type ImageEditOptions, type InboundEmail, type InboundSmsEvent, type InboxEvent, type InboxExpungeEvent, type InboxFlagsEvent, type InboxNewEvent, InboxWatcher, type InboxWatcherOptions, type InstallProgress, LOAD_SKILL_TOOL, type LinkAdvisory, type LocalSmtpConfig, MEMORY_CATEGORIES, MailReceiver, type MailReceiverOptions, MailSender, type MailSenderOptions, type MailboxInfo, type MediaBinary, type MediaCapability, type MediaCapabilityReport, type MediaFileResult, type MediaInfoResult, MediaManager, type MediaManagerOptions, type MediaStreamInfo, type MemoryCategory, type MemoryImportance, type MemoryQueryOptions, type MemoryRecaller, MemorySearchIndex, type MemorySource, type MemoryStats, OPENAI_REALTIME_URL, OPERATOR_QUERY_POLL_INTERVAL_MS, OPERATOR_QUERY_SUBJECT_TAG, OPERATOR_QUERY_TIMEOUT_MS, OPERATOR_QUERY_TIMEOUT_SENTINEL, type OpenClawPhoneMissionPolicy, type OperatorQueryNotificationInput, type OperatorQueryPollOptions, type OperatorQueryUrgency, type OperatorReplyKind, type OutboundCategory, type OutboundScanInput, type OutboundScanResult, type OutboundWarning, PHONE_CALLBACK_MAX_DELAY_SECONDS, PHONE_CALLBACK_MIN_DELAY_SECONDS, PHONE_CALL_CONTROL_PROVIDERS, 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_CALLBACK_CHAIN, PHONE_SERVER_MAX_CALL_DURATION_SECONDS, PHONE_SERVER_MAX_COST_PER_MISSION, PHONE_SERVER_MAX_EXTENSION_REQUESTS_PER_CALL, PHONE_SERVER_MAX_EXTENSION_SECONDS_PER_REQUEST, PHONE_SERVER_MAX_TOTAL_EXTENSION_SECONDS, PHONE_TASK_MAX_LENGTH, type ParsedAttachment, type ParsedEmail, type ParsedOperatorReply, type ParsedSms, type ParsedTelegramMessage, PathTraversalError, type PhoneAlternativePolicy, type PhoneCallMission, type PhoneCallbackPolicy, type PhoneConfirmPolicy, type PhoneExtensionPolicy, PhoneManager, type PhoneMissionStartValidationResult, type PhoneMissionState, type PhoneMissionTranscriptEntry, type PhoneMissionValidationIssue, type PhoneMissionValidationResult, type PhoneNumberRisk, type PhoneOperatorQuery, PhoneRateLimitError, type PhoneRegionScope, type PhoneScheduledCallback, type PhoneTransportConfig, type PhoneTransportProfile, type PhoneTransportProvider, type PhoneTransportValidationResult, PhoneWebhookAuthError, type PhoneWebhookResult, type PlanBridgeWakeArgs, type PurchasedDomain, REALTIME_AUDIO_SAMPLE_RATE, REALTIME_MAX_AUDIO_FRAME_BASE64, REALTIME_TOOL_CALL_TIMEOUT_MS, REALTIME_TOOL_DEFINITIONS, RECALL_MEMORY_TOOL, REDACTED, RELAY_PRESETS, type RealtimeBridgePort, type RealtimeBridgeTranscriptEntry, type RealtimeInboundEvent, type RealtimeInstructionOptions, type RealtimeSessionConfigOptions, type RealtimeToolCall, type RealtimeToolDefinition, type RealtimeToolHandler, type RealtimeToolResult, type RealtimeTransportAdapter, type RealtimeTransportProvider, RealtimeVoiceBridge, type RealtimeVoiceBridgeOptions, RelayBridge, type RelayBridgeOptions, type RelayConfig, RelayGateway, type RelayProvider, type RelaySearchResult, type ResumeErrorClassificationOptions, SCHEDULE_CALLBACK_TOOL, SEARCH_EMAIL_TOOL, SEARCH_SKILLS_TOOL, SPAM_THRESHOLD, type SafeJoinOptions, type SanitizeDetection, type SanitizeResult, type ScheduledCallbackRequest, type SearchCriteria, type SearchableEmail, type SecurityAdvisory, type SendMailOptions, type SendResult, type SendResultWithRaw, type SendSmsInput, type SendSmsResult, type SendTelegramMessageOptions, type SendTelegramMessageResult, ServiceManager, type ServiceStatus, type SetWebhookOptions, type SetupConfig, SetupManager, type SetupResult, type Severity, type Skill, type SkillCategory, type SkillContext, type SkillExitStrategy, type SkillSummary, type SkillTactic, type SkillValidationError, 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, TELEGRAM_API_BASE, TELEGRAM_CHUNK_SIZE, TELEGRAM_MESSAGE_LIMIT, TELEGRAM_MIN_WEBHOOK_SECRET_LENGTH, TELEGRAM_OPERATOR_QUERY_TAG, TELEGRAM_STOP_WORDS, TELEGRAM_WEBHOOK_SECRET_RE, TELEPHONY_TRANSPORT_CAPABILITIES, TWILIO_MEDIA_SAMPLE_RATE, TWILIO_REALTIME_WS_PATH, TelegramApiError, type TelegramApiOptions, type TelegramBotInfo, type TelegramChatType, type TelegramConfig, TelegramManager, type TelegramMessage, type TelegramMode, type TelephonyTransportCapability, ThreadCache, type ThreadCacheEntry, type ThreadCacheOptions, type ThreadIdInput, type ToolExecutor, type TtsGenerateOptions, type TunnelConfig, TunnelManager, type TwilioConnectedMessage, type TwilioMarkMessage, type TwilioMediaMessage, type TwilioRealtimeInboundMessage, type TwilioRealtimeOutboundMessage, TwilioRealtimeTransport, type TwilioStartMessage, type TwilioStopMessage, type TwilioStreamTwiMLOptions, UnsafeApiUrlError, type UpdateMemoryInput, type ValidatedPhoneMissionStart, type VideoAction, type VideoEditOptions, type VideoTimelineEntry, type VideoUnderstandOptions, type VideoUnderstandResult, type VoiceCloneOptions, WARNING_THRESHOLD, WEB_SEARCH_TOOL, WEB_SEARCH_UNTRUSTED_PREFIX, type WatcherOptions, type WebSearchOptions, assertWithinBase, bridgeWakeErrorMessage, bridgeWakeLastSeenAgeMs, buildApiUrl, buildElksAudioMessage, buildElksByeMessage, buildElksHandshakeMessages, buildElksInterruptMessage, buildElksListeningMessage, buildElksSendingMessage, buildInboundSecurityAdvisory, buildOpenAIRealtimeUrl, buildPhoneTransportConfig, buildRealtimeInstructions, buildRealtimeSessionConfig, buildRealtimeToolGuidance, buildTwilioClearMessage, buildTwilioMarkMessage, buildTwilioMediaMessage, buildTwilioSayTwiML, buildTwilioSignature, buildTwilioStreamTwiML, callTelegramApi, classifyEmailRoute, classifyPhoneNumberRisk, classifyResumeError, clearMediaCapabilityCache, closeDatabase, composeBridgeWakePrompt, createRealtimeTransport, createTestDatabase, createToolExecutor, debug, debugWarn, deleteTelegramWebhook, detectBinary, ensureDataDir, escapeXml, extractEmailAddress, extractVerificationCode, flushTelemetry, forgetHostSession, formatOperatorQueryTelegramMessage, getDatabase, getDatetime, getMediaCapabilities, getOperatorEmail, getSmsProvider, getTelegramChat, getTelegramMe, getTelegramUpdates, getTelegramWebhookInfo, hostSessionStoragePath, inferPhoneRegion, invalidateSkillCache, isInternalEmail, isLoopbackMailHost, isOperatorReplySender, isPhoneRegionAllowed, isSessionFresh, isTelegramChatAllowed, isTelegramStopCommand, isValidPhoneNumber, listSkills, loadHostSession, loadSkill, mapProviderSmsStatus, nextTelegramOffset, normalizeAddress, normalizePhoneNumber, normalizeSubject, operatorPrefsStoragePath, operatorQuerySubject, parseElksRealtimeMessage, parseEmail, parseGoogleVoiceSms, parseOperatorQueryReply, parseTelegramOperatorReply, parseTelegramUpdate, parseTwilioRealtimeMessage, planBridgeWake, pollForOperatorAnswer, recallMemory, recordToolCall, redactBotToken, redactObject, redactPhoneTransportConfig, redactSecret, redactSmsConfig, redactTelegramConfig, renderSkillAsPrompt, requireBinary, requireWhisperModel, resolveCallbackPolicy, resolveConfig, resolveExtensionPolicy, resolveTlsRejectUnauthorized, safeJoin, sanitizeEmail, saveConfig, saveHostSession, saveUserSkill, scanOutboundEmail, scoreEmail, searchSkills, sendTelegramMessage, setOperatorEmail, setTelegramWebhook, setTelemetryVersion, shouldSkipBridgeWakeForLiveOperator, splitTelegramMessage, startRelayBridge, stem, stripTelegramMarkdown, threadIdFor, tokenize, tryJoin, userSkillsDir, validateApiUrl, validatePhoneMissionPolicy, validatePhoneMissionStart, validatePhoneTransportProfile, validateSkill, validateTwilioSignature, webSearch };
package/dist/index.js CHANGED
@@ -5884,6 +5884,7 @@ var DEFAULT_CALLBACK_POLICY = {
5884
5884
  allowAutoCallback: true,
5885
5885
  maxCallbackChain: 2
5886
5886
  };
5887
+ var PHONE_CALLBACK_MIN_DELAY_SECONDS = 30;
5887
5888
  var PHONE_CALLBACK_MAX_DELAY_SECONDS = 7 * 24 * 60 * 60;
5888
5889
  var EU_DIAL_PREFIXES = [
5889
5890
  "+30",
@@ -11670,6 +11671,24 @@ var ServiceManager = class {
11670
11671
  "",
11671
11672
  'log "AgenticMail starting..."',
11672
11673
  "",
11674
+ "# v0.9.84 \u2014 source ~/.agenticmail/.env before exec so the API process",
11675
+ "# inherits AGENTICMAIL_MASTER_KEY, AGENTICMAIL_INBOUND_SECRET, the",
11676
+ "# Stalwart admin creds, and SMTP/IMAP/data-dir overrides. Without",
11677
+ "# this, launchd's child ran with only HOME / PATH / DATA_DIR (the",
11678
+ "# plist EnvironmentVariables block), so the API silently fell back",
11679
+ "# to a fresh-random INBOUND_SECRET on every boot and could not",
11680
+ "# decrypt master-key-protected secrets at all.",
11681
+ 'ENV_FILE="$HOME/.agenticmail/.env"',
11682
+ 'if [ -f "$ENV_FILE" ]; then',
11683
+ ' log "Sourcing $ENV_FILE"',
11684
+ " set -a # mark all sourced vars for export",
11685
+ " # shellcheck disable=SC1090",
11686
+ ' . "$ENV_FILE"',
11687
+ " set +a",
11688
+ "else",
11689
+ ' log "WARNING: $ENV_FILE not found \u2014 API will run with default config (no master key)."',
11690
+ "fi",
11691
+ "",
11673
11692
  "# Wait for Docker daemon (up to 10 minutes \u2014 Docker Desktop can be very slow on first boot)",
11674
11693
  "MAX_WAIT=600",
11675
11694
  "WAITED=0",
@@ -12095,6 +12114,16 @@ var SetupManager = class {
12095
12114
  if (existsSync9(configPath)) {
12096
12115
  try {
12097
12116
  const existing = JSON.parse(readFileSync6(configPath, "utf-8"));
12117
+ let needsRewrite = false;
12118
+ if (!existing.inboundSecret) {
12119
+ existing.inboundSecret = `inb_${randomBytes3(24).toString("hex")}`;
12120
+ needsRewrite = true;
12121
+ }
12122
+ if (needsRewrite) {
12123
+ writeFileSync7(configPath, JSON.stringify(existing, null, 2));
12124
+ chmodSync2(configPath, 384);
12125
+ this.ensureEnvHasInboundSecret(envPath, existing.inboundSecret);
12126
+ }
12098
12127
  this.generateDockerFiles(existing);
12099
12128
  return { configPath, envPath, config: existing, isNew: false };
12100
12129
  } catch {
@@ -12105,8 +12134,10 @@ var SetupManager = class {
12105
12134
  }
12106
12135
  const masterKey = `mk_${randomBytes3(24).toString("hex")}`;
12107
12136
  const stalwartPassword = randomBytes3(16).toString("hex");
12137
+ const inboundSecret = `inb_${randomBytes3(24).toString("hex")}`;
12108
12138
  const config = {
12109
12139
  masterKey,
12140
+ inboundSecret,
12110
12141
  stalwart: {
12111
12142
  url: "http://localhost:8080",
12112
12143
  adminUser: "admin",
@@ -12125,6 +12156,7 @@ STALWART_ADMIN_PASSWORD=${stalwartPassword}
12125
12156
  STALWART_URL=http://localhost:8080
12126
12157
 
12127
12158
  AGENTICMAIL_MASTER_KEY=${masterKey}
12159
+ AGENTICMAIL_INBOUND_SECRET=${inboundSecret}
12128
12160
  AGENTICMAIL_API_PORT=3829
12129
12161
  AGENTICMAIL_DATA_DIR=${dataDir}
12130
12162
 
@@ -12138,6 +12170,24 @@ IMAP_PORT=143
12138
12170
  this.generateDockerFiles(config);
12139
12171
  return { configPath, envPath, config, isNew: true };
12140
12172
  }
12173
+ /**
12174
+ * Append `AGENTICMAIL_INBOUND_SECRET=...` to .env if the file does
12175
+ * not already contain that key. Used by the lazy-mint path to make
12176
+ * sure existing installs pick up the new secret on next boot
12177
+ * without clobbering anything the operator added.
12178
+ */
12179
+ ensureEnvHasInboundSecret(envPath, secret) {
12180
+ if (!existsSync9(envPath)) return;
12181
+ try {
12182
+ const current = readFileSync6(envPath, "utf-8");
12183
+ if (/^AGENTICMAIL_INBOUND_SECRET=/m.test(current)) return;
12184
+ const updated = current + (current.endsWith("\n") ? "" : "\n") + `AGENTICMAIL_INBOUND_SECRET=${secret}
12185
+ `;
12186
+ writeFileSync7(envPath, updated);
12187
+ chmodSync2(envPath, 384);
12188
+ } catch {
12189
+ }
12190
+ }
12141
12191
  /**
12142
12192
  * Generate docker-compose.yml and stalwart.toml in ~/.agenticmail/
12143
12193
  * with the correct admin password from config.
@@ -14471,6 +14521,8 @@ export {
14471
14521
  CloudflareClient,
14472
14522
  DEFAULT_AGENT_NAME,
14473
14523
  DEFAULT_AGENT_ROLE,
14524
+ DEFAULT_CALLBACK_POLICY,
14525
+ DEFAULT_EXTENSION_POLICY,
14474
14526
  DEFAULT_REALTIME_AUDIO_FORMAT,
14475
14527
  DEFAULT_REALTIME_MODEL,
14476
14528
  DEFAULT_REALTIME_VOICE,
@@ -14483,8 +14535,11 @@ export {
14483
14535
  DomainPurchaser,
14484
14536
  ELKS_REALTIME_AUDIO_FORMATS,
14485
14537
  ELKS_REALTIME_WS_PATH,
14538
+ END_CALL_TOOL,
14539
+ EXTEND_CALL_TIME_TOOL,
14486
14540
  ElksRealtimeTransport,
14487
14541
  EmailSearchIndex,
14542
+ GET_CALL_STATUS_TOOL,
14488
14543
  GET_DATETIME_TOOL,
14489
14544
  GatewayManager,
14490
14545
  InboxWatcher,
@@ -14499,6 +14554,8 @@ export {
14499
14554
  OPERATOR_QUERY_SUBJECT_TAG,
14500
14555
  OPERATOR_QUERY_TIMEOUT_MS,
14501
14556
  OPERATOR_QUERY_TIMEOUT_SENTINEL,
14557
+ PHONE_CALLBACK_MAX_DELAY_SECONDS,
14558
+ PHONE_CALLBACK_MIN_DELAY_SECONDS,
14502
14559
  PHONE_CALL_CONTROL_PROVIDERS,
14503
14560
  PHONE_MAX_CONCURRENT_MISSIONS,
14504
14561
  PHONE_MIN_WEBHOOK_SECRET_LENGTH,
@@ -14507,8 +14564,12 @@ export {
14507
14564
  PHONE_RATE_LIMIT_PER_MINUTE,
14508
14565
  PHONE_REGION_SCOPES,
14509
14566
  PHONE_SERVER_MAX_ATTEMPTS,
14567
+ PHONE_SERVER_MAX_CALLBACK_CHAIN,
14510
14568
  PHONE_SERVER_MAX_CALL_DURATION_SECONDS,
14511
14569
  PHONE_SERVER_MAX_COST_PER_MISSION,
14570
+ PHONE_SERVER_MAX_EXTENSION_REQUESTS_PER_CALL,
14571
+ PHONE_SERVER_MAX_EXTENSION_SECONDS_PER_REQUEST,
14572
+ PHONE_SERVER_MAX_TOTAL_EXTENSION_SECONDS,
14512
14573
  PHONE_TASK_MAX_LENGTH,
14513
14574
  PathTraversalError,
14514
14575
  PhoneManager,
@@ -14524,6 +14585,7 @@ export {
14524
14585
  RealtimeVoiceBridge,
14525
14586
  RelayBridge,
14526
14587
  RelayGateway,
14588
+ SCHEDULE_CALLBACK_TOOL,
14527
14589
  SEARCH_EMAIL_TOOL,
14528
14590
  SEARCH_SKILLS_TOOL,
14529
14591
  SPAM_THRESHOLD,
@@ -14644,7 +14706,9 @@ export {
14644
14706
  renderSkillAsPrompt,
14645
14707
  requireBinary,
14646
14708
  requireWhisperModel,
14709
+ resolveCallbackPolicy,
14647
14710
  resolveConfig,
14711
+ resolveExtensionPolicy,
14648
14712
  resolveTlsRejectUnauthorized,
14649
14713
  safeJoin,
14650
14714
  sanitizeEmail,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@agenticmail/core",
3
- "version": "0.9.28",
3
+ "version": "0.9.30",
4
4
  "description": "Core SDK for AgenticMail — email, SMS, and phone call-control for AI agents",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",