@agenticmail/core 0.9.27 → 0.9.29

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,
@@ -7514,25 +7528,26 @@ var PHONE_MISSION_STATES = [
7514
7528
  "failed",
7515
7529
  "cancelled"
7516
7530
  ];
7517
- var PHONE_SERVER_MAX_CALL_DURATION_SECONDS = 3600;
7531
+ var PHONE_SERVER_MAX_CALL_DURATION_SECONDS = 7200;
7518
7532
  var PHONE_SERVER_MAX_COST_PER_MISSION = 5;
7519
7533
  var PHONE_SERVER_MAX_ATTEMPTS = 3;
7520
7534
  var PHONE_TASK_MAX_LENGTH = 2e3;
7521
- var PHONE_SERVER_MAX_EXTENSION_SECONDS_PER_REQUEST = 300;
7522
- var PHONE_SERVER_MAX_EXTENSION_REQUESTS_PER_CALL = 4;
7523
- var PHONE_SERVER_MAX_TOTAL_EXTENSION_SECONDS = 600;
7535
+ var PHONE_SERVER_MAX_EXTENSION_SECONDS_PER_REQUEST = 900;
7536
+ var PHONE_SERVER_MAX_EXTENSION_REQUESTS_PER_CALL = 8;
7537
+ var PHONE_SERVER_MAX_TOTAL_EXTENSION_SECONDS = 3600;
7524
7538
  var DEFAULT_EXTENSION_POLICY = {
7525
- maxSecondsPerRequest: 120,
7526
- // 2 minutes
7527
- maxRequestsPerCall: 2,
7528
- maxTotalExtensionSeconds: 300
7539
+ maxSecondsPerRequest: 300,
7529
7540
  // 5 minutes
7541
+ maxRequestsPerCall: 4,
7542
+ maxTotalExtensionSeconds: 1200
7543
+ // 20 minutes
7530
7544
  };
7531
7545
  var PHONE_SERVER_MAX_CALLBACK_CHAIN = 3;
7532
7546
  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",
@@ -10745,6 +10760,20 @@ var SCHEDULE_CALLBACK_TOOL = {
10745
10760
  required: ["delay_seconds", "summary_for_next_call"]
10746
10761
  }
10747
10762
  };
10763
+ var END_CALL_TOOL = {
10764
+ type: "function",
10765
+ name: "end_call",
10766
+ description: `Hang up the call. You MUST call this AFTER you have said goodbye and the conversation is complete \u2014 saying "I'll hang up now" is not enough on its own, the call stays open until you actually call this tool. Use it when: the task is done and you have signed off, the caller has indicated the conversation is over, you have scheduled a callback and said goodbye, or the caller has stopped responding for an extended period. Once called the call drops immediately; you cannot un-hang-up.`,
10767
+ parameters: {
10768
+ type: "object",
10769
+ properties: {
10770
+ reason: {
10771
+ type: "string",
10772
+ description: 'One short line for the audit trail \u2014 e.g. "task complete", "caller said bye", "scheduled callback, signing off". Optional but recommended.'
10773
+ }
10774
+ }
10775
+ }
10776
+ };
10748
10777
  var REALTIME_TOOL_DEFINITIONS = {
10749
10778
  ask_operator: ASK_OPERATOR_TOOL,
10750
10779
  web_search: WEB_SEARCH_TOOL,
@@ -10755,7 +10784,8 @@ var REALTIME_TOOL_DEFINITIONS = {
10755
10784
  load_skill: LOAD_SKILL_TOOL,
10756
10785
  get_call_status: GET_CALL_STATUS_TOOL,
10757
10786
  extend_call_time: EXTEND_CALL_TIME_TOOL,
10758
- schedule_callback: SCHEDULE_CALLBACK_TOOL
10787
+ schedule_callback: SCHEDULE_CALLBACK_TOOL,
10788
+ end_call: END_CALL_TOOL
10759
10789
  };
10760
10790
  function buildRealtimeToolGuidance(tools) {
10761
10791
  if (tools.length === 0) return "";
@@ -10802,6 +10832,24 @@ A skill's rendered playbook is now part of your instructions for the rest of the
10802
10832
  "When in doubt \u2014 out of time, out of extensions, the caller is uncertain \u2014 preferred order is: wrap up gracefully \u2192 schedule_callback \u2192 sign off. Never go silent or invent excuses; the right move is always a clean handoff to a future call."
10803
10833
  );
10804
10834
  }
10835
+ if (names.has("end_call")) {
10836
+ lines.push(
10837
+ "# Hanging up \u2014 you must call end_call to actually drop the line",
10838
+ `SAYING "I'll hang up now" or "goodbye" does NOT drop the call \u2014 the line stays open until you call the end_call tool. This is the single most important habit on a real phone call: after you have said your goodbye sentence, IMMEDIATELY call end_call({ reason: "..." }). Do not wait for the caller to hang up first; do not assume the system will close the line for you. Call end_call yourself.`,
10839
+ "",
10840
+ "When to call end_call:",
10841
+ "- The task is complete and you have just said goodbye.",
10842
+ '- The caller said "thanks, bye" or otherwise signalled they are done.',
10843
+ `- You scheduled a callback and said "I'll call you back at <when>".`,
10844
+ "- The caller has gone silent for an extended stretch and is clearly not coming back.",
10845
+ "- The operator told you to hang up.",
10846
+ "",
10847
+ "Do NOT call end_call:",
10848
+ "- Mid-conversation when there is still pending business.",
10849
+ "- Because you ran into a tool error \u2014 handle it and keep the call going.",
10850
+ "- During a hold while a tool is running \u2014 let the tool finish."
10851
+ );
10852
+ }
10805
10853
  return lines.join("\n");
10806
10854
  }
10807
10855
  function toolErrorText(err) {
@@ -11681,8 +11729,10 @@ var RealtimeVoiceBridge = class {
11681
11729
  }
11682
11730
  let granted = Math.min(asked, pol.maxSecondsPerRequest, remainingBudgetSeconds);
11683
11731
  const elapsedSeconds = Math.floor((this.nowFn() - this.callStartedAtMs) / 1e3);
11684
- const maxAllowedFromStart = 3600;
11685
- const hardCeilingRoom = Math.max(0, maxAllowedFromStart - (elapsedSeconds + this.getTimeRemainingSeconds()));
11732
+ const hardCeilingRoom = Math.max(
11733
+ 0,
11734
+ PHONE_SERVER_MAX_CALL_DURATION_SECONDS - (elapsedSeconds + this.getTimeRemainingSeconds())
11735
+ );
11686
11736
  granted = Math.min(granted, hardCeilingRoom);
11687
11737
  if (granted <= 0) {
11688
11738
  return {
@@ -11921,6 +11971,31 @@ var RealtimeVoiceBridge = class {
11921
11971
  return "\u2026\n" + joined.slice(joined.length - MAX_CALLBACK_TRANSCRIPT_DIGEST_LENGTH + 2);
11922
11972
  }
11923
11973
  // ─── Teardown ─────────────────────────────────────────
11974
+ /**
11975
+ * v0.9.82 — agent-initiated hangup. Called when the `end_call` tool
11976
+ * fires. Logs a marker, then routes through {@link end} so the
11977
+ * carrier sees the bye frame and `onEnd` fires exactly once (the
11978
+ * same teardown path the human-hangup case takes). The "agent-
11979
+ * requested" reason flows through to the mission transcript so a
11980
+ * post-call audit can tell apart "agent hung up" from "human hung
11981
+ * up" from "time budget exceeded".
11982
+ *
11983
+ * Returns the structured result the tool handler echoes back to the
11984
+ * model — even though by the time the model receives it the line
11985
+ * will already be closed, keeping a consistent return shape lets the
11986
+ * executor JSON-stringify deterministically.
11987
+ */
11988
+ endByAgentRequest(reason) {
11989
+ if (this.ended) {
11990
+ return { ok: false, message: "Call has already ended." };
11991
+ }
11992
+ const trimmed = (reason ?? "").trim();
11993
+ this.emitTranscript("system", `Agent requested hangup. Reason: ${trimmed || "unspecified"}`, {
11994
+ endedByAgent: true
11995
+ });
11996
+ this.end("agent-requested");
11997
+ return { ok: true, message: "Call ended." };
11998
+ }
11924
11999
  /**
11925
12000
  * End the bridge. Idempotent — the first call wins, later calls are
11926
12001
  * no-ops. Sends the carrier's end-of-call frame (if it has one — 46elks
@@ -16045,6 +16120,8 @@ init_skills();
16045
16120
  CloudflareClient,
16046
16121
  DEFAULT_AGENT_NAME,
16047
16122
  DEFAULT_AGENT_ROLE,
16123
+ DEFAULT_CALLBACK_POLICY,
16124
+ DEFAULT_EXTENSION_POLICY,
16048
16125
  DEFAULT_REALTIME_AUDIO_FORMAT,
16049
16126
  DEFAULT_REALTIME_MODEL,
16050
16127
  DEFAULT_REALTIME_VOICE,
@@ -16057,8 +16134,11 @@ init_skills();
16057
16134
  DomainPurchaser,
16058
16135
  ELKS_REALTIME_AUDIO_FORMATS,
16059
16136
  ELKS_REALTIME_WS_PATH,
16137
+ END_CALL_TOOL,
16138
+ EXTEND_CALL_TIME_TOOL,
16060
16139
  ElksRealtimeTransport,
16061
16140
  EmailSearchIndex,
16141
+ GET_CALL_STATUS_TOOL,
16062
16142
  GET_DATETIME_TOOL,
16063
16143
  GatewayManager,
16064
16144
  InboxWatcher,
@@ -16073,6 +16153,8 @@ init_skills();
16073
16153
  OPERATOR_QUERY_SUBJECT_TAG,
16074
16154
  OPERATOR_QUERY_TIMEOUT_MS,
16075
16155
  OPERATOR_QUERY_TIMEOUT_SENTINEL,
16156
+ PHONE_CALLBACK_MAX_DELAY_SECONDS,
16157
+ PHONE_CALLBACK_MIN_DELAY_SECONDS,
16076
16158
  PHONE_CALL_CONTROL_PROVIDERS,
16077
16159
  PHONE_MAX_CONCURRENT_MISSIONS,
16078
16160
  PHONE_MIN_WEBHOOK_SECRET_LENGTH,
@@ -16081,8 +16163,12 @@ init_skills();
16081
16163
  PHONE_RATE_LIMIT_PER_MINUTE,
16082
16164
  PHONE_REGION_SCOPES,
16083
16165
  PHONE_SERVER_MAX_ATTEMPTS,
16166
+ PHONE_SERVER_MAX_CALLBACK_CHAIN,
16084
16167
  PHONE_SERVER_MAX_CALL_DURATION_SECONDS,
16085
16168
  PHONE_SERVER_MAX_COST_PER_MISSION,
16169
+ PHONE_SERVER_MAX_EXTENSION_REQUESTS_PER_CALL,
16170
+ PHONE_SERVER_MAX_EXTENSION_SECONDS_PER_REQUEST,
16171
+ PHONE_SERVER_MAX_TOTAL_EXTENSION_SECONDS,
16086
16172
  PHONE_TASK_MAX_LENGTH,
16087
16173
  PathTraversalError,
16088
16174
  PhoneManager,
@@ -16098,6 +16184,7 @@ init_skills();
16098
16184
  RealtimeVoiceBridge,
16099
16185
  RelayBridge,
16100
16186
  RelayGateway,
16187
+ SCHEDULE_CALLBACK_TOOL,
16101
16188
  SEARCH_EMAIL_TOOL,
16102
16189
  SEARCH_SKILLS_TOOL,
16103
16190
  SPAM_THRESHOLD,
@@ -16218,7 +16305,9 @@ init_skills();
16218
16305
  renderSkillAsPrompt,
16219
16306
  requireBinary,
16220
16307
  requireWhisperModel,
16308
+ resolveCallbackPolicy,
16221
16309
  resolveConfig,
16310
+ resolveExtensionPolicy,
16222
16311
  resolveTlsRejectUnauthorized,
16223
16312
  safeJoin,
16224
16313
  sanitizeEmail,
package/dist/index.d.cts CHANGED
@@ -2618,11 +2618,56 @@ type PhoneNumberRisk = 'invalid' | 'standard' | 'premium_or_special';
2618
2618
  * be MORE restrictive than the server, never less. A phone mission places
2619
2619
  * real, billed calls — these bounds are the financial blast-radius cap.
2620
2620
  */
2621
- declare const PHONE_SERVER_MAX_CALL_DURATION_SECONDS = 3600;
2621
+ declare const PHONE_SERVER_MAX_CALL_DURATION_SECONDS = 7200;
2622
2622
  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
  /**
@@ -3692,6 +3788,24 @@ declare class RealtimeVoiceBridge {
3692
3788
  * Always honours {@link MAX_CALLBACK_TRANSCRIPT_DIGEST_LENGTH}.
3693
3789
  */
3694
3790
  private composeTranscriptDigest;
3791
+ /**
3792
+ * v0.9.82 — agent-initiated hangup. Called when the `end_call` tool
3793
+ * fires. Logs a marker, then routes through {@link end} so the
3794
+ * carrier sees the bye frame and `onEnd` fires exactly once (the
3795
+ * same teardown path the human-hangup case takes). The "agent-
3796
+ * requested" reason flows through to the mission transcript so a
3797
+ * post-call audit can tell apart "agent hung up" from "human hung
3798
+ * up" from "time budget exceeded".
3799
+ *
3800
+ * Returns the structured result the tool handler echoes back to the
3801
+ * model — even though by the time the model receives it the line
3802
+ * will already be closed, keeping a consistent return shape lets the
3803
+ * executor JSON-stringify deterministically.
3804
+ */
3805
+ endByAgentRequest(reason?: string): {
3806
+ ok: boolean;
3807
+ message: string;
3808
+ };
3695
3809
  /**
3696
3810
  * End the bridge. Idempotent — the first call wins, later calls are
3697
3811
  * no-ops. Sends the carrier's end-of-call frame (if it has one — 46elks
@@ -3803,6 +3917,38 @@ interface PhoneWebhookResult {
3803
3917
  mission: PhoneCallMission;
3804
3918
  action: Record<string, unknown>;
3805
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
+ }
3806
3952
  declare function redactPhoneTransportConfig(config: PhoneTransportConfig): PhoneTransportConfig;
3807
3953
  declare class PhoneManager {
3808
3954
  private db;
@@ -5950,4 +6096,4 @@ declare function userSkillsDir(): string;
5950
6096
  */
5951
6097
  declare function renderSkillAsPrompt(skill: Skill): string;
5952
6098
 
5953
- 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 };
6099
+ 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
@@ -2618,11 +2618,56 @@ type PhoneNumberRisk = 'invalid' | 'standard' | 'premium_or_special';
2618
2618
  * be MORE restrictive than the server, never less. A phone mission places
2619
2619
  * real, billed calls — these bounds are the financial blast-radius cap.
2620
2620
  */
2621
- declare const PHONE_SERVER_MAX_CALL_DURATION_SECONDS = 3600;
2621
+ declare const PHONE_SERVER_MAX_CALL_DURATION_SECONDS = 7200;
2622
2622
  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
  /**
@@ -3692,6 +3788,24 @@ declare class RealtimeVoiceBridge {
3692
3788
  * Always honours {@link MAX_CALLBACK_TRANSCRIPT_DIGEST_LENGTH}.
3693
3789
  */
3694
3790
  private composeTranscriptDigest;
3791
+ /**
3792
+ * v0.9.82 — agent-initiated hangup. Called when the `end_call` tool
3793
+ * fires. Logs a marker, then routes through {@link end} so the
3794
+ * carrier sees the bye frame and `onEnd` fires exactly once (the
3795
+ * same teardown path the human-hangup case takes). The "agent-
3796
+ * requested" reason flows through to the mission transcript so a
3797
+ * post-call audit can tell apart "agent hung up" from "human hung
3798
+ * up" from "time budget exceeded".
3799
+ *
3800
+ * Returns the structured result the tool handler echoes back to the
3801
+ * model — even though by the time the model receives it the line
3802
+ * will already be closed, keeping a consistent return shape lets the
3803
+ * executor JSON-stringify deterministically.
3804
+ */
3805
+ endByAgentRequest(reason?: string): {
3806
+ ok: boolean;
3807
+ message: string;
3808
+ };
3695
3809
  /**
3696
3810
  * End the bridge. Idempotent — the first call wins, later calls are
3697
3811
  * no-ops. Sends the carrier's end-of-call frame (if it has one — 46elks
@@ -3803,6 +3917,38 @@ interface PhoneWebhookResult {
3803
3917
  mission: PhoneCallMission;
3804
3918
  action: Record<string, unknown>;
3805
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
+ }
3806
3952
  declare function redactPhoneTransportConfig(config: PhoneTransportConfig): PhoneTransportConfig;
3807
3953
  declare class PhoneManager {
3808
3954
  private db;
@@ -5950,4 +6096,4 @@ declare function userSkillsDir(): string;
5950
6096
  */
5951
6097
  declare function renderSkillAsPrompt(skill: Skill): string;
5952
6098
 
5953
- 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 };
6099
+ 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
@@ -5865,25 +5865,26 @@ var PHONE_MISSION_STATES = [
5865
5865
  "failed",
5866
5866
  "cancelled"
5867
5867
  ];
5868
- var PHONE_SERVER_MAX_CALL_DURATION_SECONDS = 3600;
5868
+ var PHONE_SERVER_MAX_CALL_DURATION_SECONDS = 7200;
5869
5869
  var PHONE_SERVER_MAX_COST_PER_MISSION = 5;
5870
5870
  var PHONE_SERVER_MAX_ATTEMPTS = 3;
5871
5871
  var PHONE_TASK_MAX_LENGTH = 2e3;
5872
- var PHONE_SERVER_MAX_EXTENSION_SECONDS_PER_REQUEST = 300;
5873
- var PHONE_SERVER_MAX_EXTENSION_REQUESTS_PER_CALL = 4;
5874
- var PHONE_SERVER_MAX_TOTAL_EXTENSION_SECONDS = 600;
5872
+ var PHONE_SERVER_MAX_EXTENSION_SECONDS_PER_REQUEST = 900;
5873
+ var PHONE_SERVER_MAX_EXTENSION_REQUESTS_PER_CALL = 8;
5874
+ var PHONE_SERVER_MAX_TOTAL_EXTENSION_SECONDS = 3600;
5875
5875
  var DEFAULT_EXTENSION_POLICY = {
5876
- maxSecondsPerRequest: 120,
5877
- // 2 minutes
5878
- maxRequestsPerCall: 2,
5879
- maxTotalExtensionSeconds: 300
5876
+ maxSecondsPerRequest: 300,
5880
5877
  // 5 minutes
5878
+ maxRequestsPerCall: 4,
5879
+ maxTotalExtensionSeconds: 1200
5880
+ // 20 minutes
5881
5881
  };
5882
5882
  var PHONE_SERVER_MAX_CALLBACK_CHAIN = 3;
5883
5883
  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",
@@ -9096,6 +9097,20 @@ var SCHEDULE_CALLBACK_TOOL = {
9096
9097
  required: ["delay_seconds", "summary_for_next_call"]
9097
9098
  }
9098
9099
  };
9100
+ var END_CALL_TOOL = {
9101
+ type: "function",
9102
+ name: "end_call",
9103
+ description: `Hang up the call. You MUST call this AFTER you have said goodbye and the conversation is complete \u2014 saying "I'll hang up now" is not enough on its own, the call stays open until you actually call this tool. Use it when: the task is done and you have signed off, the caller has indicated the conversation is over, you have scheduled a callback and said goodbye, or the caller has stopped responding for an extended period. Once called the call drops immediately; you cannot un-hang-up.`,
9104
+ parameters: {
9105
+ type: "object",
9106
+ properties: {
9107
+ reason: {
9108
+ type: "string",
9109
+ description: 'One short line for the audit trail \u2014 e.g. "task complete", "caller said bye", "scheduled callback, signing off". Optional but recommended.'
9110
+ }
9111
+ }
9112
+ }
9113
+ };
9099
9114
  var REALTIME_TOOL_DEFINITIONS = {
9100
9115
  ask_operator: ASK_OPERATOR_TOOL,
9101
9116
  web_search: WEB_SEARCH_TOOL,
@@ -9106,7 +9121,8 @@ var REALTIME_TOOL_DEFINITIONS = {
9106
9121
  load_skill: LOAD_SKILL_TOOL,
9107
9122
  get_call_status: GET_CALL_STATUS_TOOL,
9108
9123
  extend_call_time: EXTEND_CALL_TIME_TOOL,
9109
- schedule_callback: SCHEDULE_CALLBACK_TOOL
9124
+ schedule_callback: SCHEDULE_CALLBACK_TOOL,
9125
+ end_call: END_CALL_TOOL
9110
9126
  };
9111
9127
  function buildRealtimeToolGuidance(tools) {
9112
9128
  if (tools.length === 0) return "";
@@ -9153,6 +9169,24 @@ A skill's rendered playbook is now part of your instructions for the rest of the
9153
9169
  "When in doubt \u2014 out of time, out of extensions, the caller is uncertain \u2014 preferred order is: wrap up gracefully \u2192 schedule_callback \u2192 sign off. Never go silent or invent excuses; the right move is always a clean handoff to a future call."
9154
9170
  );
9155
9171
  }
9172
+ if (names.has("end_call")) {
9173
+ lines.push(
9174
+ "# Hanging up \u2014 you must call end_call to actually drop the line",
9175
+ `SAYING "I'll hang up now" or "goodbye" does NOT drop the call \u2014 the line stays open until you call the end_call tool. This is the single most important habit on a real phone call: after you have said your goodbye sentence, IMMEDIATELY call end_call({ reason: "..." }). Do not wait for the caller to hang up first; do not assume the system will close the line for you. Call end_call yourself.`,
9176
+ "",
9177
+ "When to call end_call:",
9178
+ "- The task is complete and you have just said goodbye.",
9179
+ '- The caller said "thanks, bye" or otherwise signalled they are done.',
9180
+ `- You scheduled a callback and said "I'll call you back at <when>".`,
9181
+ "- The caller has gone silent for an extended stretch and is clearly not coming back.",
9182
+ "- The operator told you to hang up.",
9183
+ "",
9184
+ "Do NOT call end_call:",
9185
+ "- Mid-conversation when there is still pending business.",
9186
+ "- Because you ran into a tool error \u2014 handle it and keep the call going.",
9187
+ "- During a hold while a tool is running \u2014 let the tool finish."
9188
+ );
9189
+ }
9156
9190
  return lines.join("\n");
9157
9191
  }
9158
9192
  function toolErrorText(err) {
@@ -10032,8 +10066,10 @@ var RealtimeVoiceBridge = class {
10032
10066
  }
10033
10067
  let granted = Math.min(asked, pol.maxSecondsPerRequest, remainingBudgetSeconds);
10034
10068
  const elapsedSeconds = Math.floor((this.nowFn() - this.callStartedAtMs) / 1e3);
10035
- const maxAllowedFromStart = 3600;
10036
- const hardCeilingRoom = Math.max(0, maxAllowedFromStart - (elapsedSeconds + this.getTimeRemainingSeconds()));
10069
+ const hardCeilingRoom = Math.max(
10070
+ 0,
10071
+ PHONE_SERVER_MAX_CALL_DURATION_SECONDS - (elapsedSeconds + this.getTimeRemainingSeconds())
10072
+ );
10037
10073
  granted = Math.min(granted, hardCeilingRoom);
10038
10074
  if (granted <= 0) {
10039
10075
  return {
@@ -10272,6 +10308,31 @@ var RealtimeVoiceBridge = class {
10272
10308
  return "\u2026\n" + joined.slice(joined.length - MAX_CALLBACK_TRANSCRIPT_DIGEST_LENGTH + 2);
10273
10309
  }
10274
10310
  // ─── Teardown ─────────────────────────────────────────
10311
+ /**
10312
+ * v0.9.82 — agent-initiated hangup. Called when the `end_call` tool
10313
+ * fires. Logs a marker, then routes through {@link end} so the
10314
+ * carrier sees the bye frame and `onEnd` fires exactly once (the
10315
+ * same teardown path the human-hangup case takes). The "agent-
10316
+ * requested" reason flows through to the mission transcript so a
10317
+ * post-call audit can tell apart "agent hung up" from "human hung
10318
+ * up" from "time budget exceeded".
10319
+ *
10320
+ * Returns the structured result the tool handler echoes back to the
10321
+ * model — even though by the time the model receives it the line
10322
+ * will already be closed, keeping a consistent return shape lets the
10323
+ * executor JSON-stringify deterministically.
10324
+ */
10325
+ endByAgentRequest(reason) {
10326
+ if (this.ended) {
10327
+ return { ok: false, message: "Call has already ended." };
10328
+ }
10329
+ const trimmed = (reason ?? "").trim();
10330
+ this.emitTranscript("system", `Agent requested hangup. Reason: ${trimmed || "unspecified"}`, {
10331
+ endedByAgent: true
10332
+ });
10333
+ this.end("agent-requested");
10334
+ return { ok: true, message: "Call ended." };
10335
+ }
10275
10336
  /**
10276
10337
  * End the bridge. Idempotent — the first call wins, later calls are
10277
10338
  * no-ops. Sends the carrier's end-of-call frame (if it has one — 46elks
@@ -14411,6 +14472,8 @@ export {
14411
14472
  CloudflareClient,
14412
14473
  DEFAULT_AGENT_NAME,
14413
14474
  DEFAULT_AGENT_ROLE,
14475
+ DEFAULT_CALLBACK_POLICY,
14476
+ DEFAULT_EXTENSION_POLICY,
14414
14477
  DEFAULT_REALTIME_AUDIO_FORMAT,
14415
14478
  DEFAULT_REALTIME_MODEL,
14416
14479
  DEFAULT_REALTIME_VOICE,
@@ -14423,8 +14486,11 @@ export {
14423
14486
  DomainPurchaser,
14424
14487
  ELKS_REALTIME_AUDIO_FORMATS,
14425
14488
  ELKS_REALTIME_WS_PATH,
14489
+ END_CALL_TOOL,
14490
+ EXTEND_CALL_TIME_TOOL,
14426
14491
  ElksRealtimeTransport,
14427
14492
  EmailSearchIndex,
14493
+ GET_CALL_STATUS_TOOL,
14428
14494
  GET_DATETIME_TOOL,
14429
14495
  GatewayManager,
14430
14496
  InboxWatcher,
@@ -14439,6 +14505,8 @@ export {
14439
14505
  OPERATOR_QUERY_SUBJECT_TAG,
14440
14506
  OPERATOR_QUERY_TIMEOUT_MS,
14441
14507
  OPERATOR_QUERY_TIMEOUT_SENTINEL,
14508
+ PHONE_CALLBACK_MAX_DELAY_SECONDS,
14509
+ PHONE_CALLBACK_MIN_DELAY_SECONDS,
14442
14510
  PHONE_CALL_CONTROL_PROVIDERS,
14443
14511
  PHONE_MAX_CONCURRENT_MISSIONS,
14444
14512
  PHONE_MIN_WEBHOOK_SECRET_LENGTH,
@@ -14447,8 +14515,12 @@ export {
14447
14515
  PHONE_RATE_LIMIT_PER_MINUTE,
14448
14516
  PHONE_REGION_SCOPES,
14449
14517
  PHONE_SERVER_MAX_ATTEMPTS,
14518
+ PHONE_SERVER_MAX_CALLBACK_CHAIN,
14450
14519
  PHONE_SERVER_MAX_CALL_DURATION_SECONDS,
14451
14520
  PHONE_SERVER_MAX_COST_PER_MISSION,
14521
+ PHONE_SERVER_MAX_EXTENSION_REQUESTS_PER_CALL,
14522
+ PHONE_SERVER_MAX_EXTENSION_SECONDS_PER_REQUEST,
14523
+ PHONE_SERVER_MAX_TOTAL_EXTENSION_SECONDS,
14452
14524
  PHONE_TASK_MAX_LENGTH,
14453
14525
  PathTraversalError,
14454
14526
  PhoneManager,
@@ -14464,6 +14536,7 @@ export {
14464
14536
  RealtimeVoiceBridge,
14465
14537
  RelayBridge,
14466
14538
  RelayGateway,
14539
+ SCHEDULE_CALLBACK_TOOL,
14467
14540
  SEARCH_EMAIL_TOOL,
14468
14541
  SEARCH_SKILLS_TOOL,
14469
14542
  SPAM_THRESHOLD,
@@ -14584,7 +14657,9 @@ export {
14584
14657
  renderSkillAsPrompt,
14585
14658
  requireBinary,
14586
14659
  requireWhisperModel,
14660
+ resolveCallbackPolicy,
14587
14661
  resolveConfig,
14662
+ resolveExtensionPolicy,
14588
14663
  resolveTlsRejectUnauthorized,
14589
14664
  safeJoin,
14590
14665
  sanitizeEmail,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@agenticmail/core",
3
- "version": "0.9.27",
3
+ "version": "0.9.29",
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",