lua-cli 3.17.6 → 3.20.0

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.
@@ -12,7 +12,7 @@ import { ZodType } from 'zod';
12
12
  *
13
13
  * Intentionally a narrow, safe subset of the public `ChatMessageDto` — omits
14
14
  * sandbox-only overrides (`skillOverride`, `preprocessorOverride`, etc.),
15
- * webhook payloads, navigation hints, and persona override.
15
+ * navigation hints, and persona override.
16
16
  *
17
17
  * Either `prompt` or `messages` must be provided. When `prompt` is given, it is
18
18
  * converted into a single `{ role: 'user', content: [{ type: 'text', text: prompt }] }`
@@ -27,6 +27,10 @@ declare interface AgentInvocationInput {
27
27
  systemPrompt?: string;
28
28
  /** Additional runtime context attached to the request. */
29
29
  runtimeContext?: string;
30
+ /** Client-side context (e.g. the caller's IANA timezone) for this invocation. */
31
+ clientContext?: {
32
+ timezone?: string;
33
+ };
30
34
  /**
31
35
  * Optional thread ID suffix for conversation scoping. When omitted, the
32
36
  * invocation flows into the caller-user's default chat thread with the
@@ -48,6 +52,13 @@ declare interface AgentInvocationInput {
48
52
  * a user-authenticated turn — the turn's user is always used, no impersonation.
49
53
  */
50
54
  userId?: string;
55
+ /**
56
+ * Raw payload from the trigger source (webhook body, trigger envelope).
57
+ * Surfaces on the invoked agent's `runtimeContext` as `webhookPayload` and
58
+ * flows to tool executions — turn-scoped, not persisted to memory. Listed in
59
+ * the original BAC-107 spec; wired through as part of PRO-186.
60
+ */
61
+ webhookPayload?: unknown;
51
62
  }
52
63
 
53
64
  /**
@@ -79,11 +90,19 @@ declare interface AgentInvocationOutput {
79
90
  }
80
91
 
81
92
  /**
82
- * Per-agent LLM call settings. Maps directly onto Mastra's
93
+ * Per-agent LLM call settings PLUS normalized reasoning config. The
94
+ * `CallSettings` leafs (`temperature`, `topP`, …) map directly onto Mastra's
83
95
  * `agent.stream({ modelSettings })` / `agent.generate({ modelSettings })`,
84
- * which in turn maps onto the AI SDK's `CallSettings`. Pass-through:
85
- * we don't validate ranges here; the provider will reject invalid combos
86
- * (e.g. topP > 1, presencePenalty out of provider range).
96
+ * which in turn maps onto the AI SDK's `CallSettings` — pass-through, we
97
+ * don't validate ranges here; the provider will reject invalid combos (e.g.
98
+ * topP > 1, presencePenalty out of provider range).
99
+ *
100
+ * `reasoning` is NOT a `CallSettings` key — it's the agent-level tier of the
101
+ * `ModelRequestOptions` precedence chain (request > agent `reasoning` >
102
+ * per-model DB `modelOptions` > code defaults). lua-core splits this bag
103
+ * before calling Mastra: `reasoning` is stripped and merged into the
104
+ * provider-options resolution seam instead of being passed through as a
105
+ * `CallSettings` field.
87
106
  *
88
107
  * Deliberately excludes `abortSignal` (not serializable), `headers`
89
108
  * (security — could exfiltrate credentials), and `maxRetries` (platform
@@ -106,6 +125,17 @@ export declare interface AgentModelSettings {
106
125
  stopSequences?: string[];
107
126
  /** Random seed for deterministic sampling (provider support varies). */
108
127
  seed?: number;
128
+ /**
129
+ * Per-agent reasoning default. Lower precedence than a per-request
130
+ * `options.reasoning` override; higher precedence than the per-model DB
131
+ * `modelOptions.reasoning` override. Verbosity is deliberately NOT
132
+ * available here — it stays request-level only (`ModelRequestOptions.verbosity`).
133
+ */
134
+ reasoning?: {
135
+ effort?: ReasoningEffort;
136
+ /** Whether to surface the reasoning trace to the caller. Default true. */
137
+ show?: boolean;
138
+ };
109
139
  }
110
140
 
111
141
  export declare const Agents: AgentsApi;
@@ -627,6 +657,23 @@ declare interface BatchingConfig {
627
657
  serializeProcessing?: boolean;
628
658
  }
629
659
 
660
+ /**
661
+ * Browser switch config (LuaBrowser). `browser: true` is the zero-code form —
662
+ * the agent gets browser tools injected, like `searchWeb`, routed to the user's
663
+ * local browser (desktop) or the Browser-Use cloud fallback. The object form
664
+ * adds optional policy.
665
+ */
666
+ declare interface BrowserSwitchConfig {
667
+ /** Preferred engine; 'auto' lets the platform pick local (desktop) vs cloud. */
668
+ engine?: 'auto' | 'browser-use' | 'agent-browser';
669
+ /** Egress allowlist — domains the browser may navigate/sub-request. */
670
+ allowedDomains?: string[];
671
+ /** Names of vault credential entries the agent may use (never raw secrets). */
672
+ credentials?: string[];
673
+ /** Hard cap on a single browser session's duration (cost control). */
674
+ maxSessionMinutes?: number;
675
+ }
676
+
630
677
  /**
631
678
  * CDN API
632
679
  * Upload and retrieve files from the Lua CDN
@@ -688,6 +735,182 @@ export declare const CDN: {
688
735
  */
689
736
  export declare type Channel = 'web' | 'whatsapp' | 'facebook' | 'instagram' | 'slack' | 'teams' | 'front' | 'messagebird' | 'api' | 'dev' | 'email' | string;
690
737
 
738
+ /** Channels accepted by the v1 unified send. Warm-only channels (teams,
739
+ * instagram, messenger) require a prior inbound conversation. */
740
+ export declare const CHANNEL_SEND_CHANNELS: readonly ["whatsapp", "sms", "email", "webchat", "teams", "instagram", "messenger"];
741
+
742
+ export declare const Channels: ChannelsApi;
743
+
744
+ /**
745
+ * Channels API — send outbound messages over any supported channel from inside
746
+ * a job, webhook, or skill tool.
747
+ *
748
+ * Use `Channels.send` for text messages on whatsapp/sms/email/webchat and other
749
+ * channels. Use the nested namespaces for channel-specific payloads.
750
+ *
751
+ * A successful send with a failed persistence write returns `{ delivered: true,
752
+ * persisted: false, warning: '...' }` — this is HTTP 200 and is NOT thrown.
753
+ *
754
+ * @example
755
+ * ```typescript
756
+ * // Send a text message over WhatsApp
757
+ * await Channels.send({
758
+ * channel: 'whatsapp',
759
+ * to: { phoneNumber: '+15551234567' },
760
+ * text: 'Your order has shipped!',
761
+ * });
762
+ *
763
+ * // Send a WhatsApp template
764
+ * await Channels.whatsapp.sendTemplate({
765
+ * to: { phoneNumber: '+15551234567' },
766
+ * templateName: 'order_shipped',
767
+ * languageCode: 'en',
768
+ * });
769
+ *
770
+ * // React to a WhatsApp message
771
+ * await Channels.whatsapp.sendReaction({
772
+ * to: { phoneNumber: '+15551234567' },
773
+ * messageId: 'wamid.HBgL...',
774
+ * emoji: '👍',
775
+ * });
776
+ *
777
+ * // Send an email
778
+ * await Channels.email.send({
779
+ * to: { email: 'customer@example.com' },
780
+ * subject: 'Your order',
781
+ * html: '<p>Thanks for your order!</p>',
782
+ * });
783
+ * ```
784
+ */
785
+ export declare interface ChannelsApi {
786
+ /**
787
+ * Send a text message on any supported channel.
788
+ * Returns `ChannelSendOutput` — check `persisted` if memory durability matters.
789
+ *
790
+ * @example
791
+ * ```typescript
792
+ * const result = await Channels.send({
793
+ * channel: 'email',
794
+ * to: { userId: 'u-42' },
795
+ * text: 'Hi from Lua!',
796
+ * });
797
+ * if (!result.persisted) console.warn(result.warning);
798
+ * ```
799
+ */
800
+ send(input: ChannelSendInput): Promise<ChannelSendOutput>;
801
+ /** WhatsApp-specific send operations. */
802
+ whatsapp: {
803
+ /**
804
+ * Send a pre-approved WhatsApp Business template.
805
+ *
806
+ * @example
807
+ * ```typescript
808
+ * await Channels.whatsapp.sendTemplate({
809
+ * to: { phoneNumber: '+447551166594' },
810
+ * templateName: 'order_update',
811
+ * languageCode: 'en',
812
+ * components: [{ type: 'body', parameters: [{ type: 'text', text: 'ORD-99' }] }],
813
+ * });
814
+ * ```
815
+ */
816
+ sendTemplate(input: WhatsAppTemplateSendInput): Promise<ChannelSendOutput>;
817
+ /**
818
+ * React to a WhatsApp message with a single emoji.
819
+ *
820
+ * `messageId` is the vendor message id (`wamid...`) — e.g. read it off an
821
+ * inbound message from the channel webhook/history — and must be ≤30 days
822
+ * old (Meta limit). Pass `emoji: ''` to remove an existing reaction.
823
+ *
824
+ * @example
825
+ * ```typescript
826
+ * await Channels.whatsapp.sendReaction({
827
+ * to: { phoneNumber: '+447551166594' },
828
+ * messageId: 'wamid.HBgL...',
829
+ * emoji: '👍',
830
+ * });
831
+ * ```
832
+ */
833
+ sendReaction(input: WhatsAppReactionSendInput): Promise<ChannelSendOutput>;
834
+ };
835
+ /** Email-specific send operations. */
836
+ email: {
837
+ /**
838
+ * Send an email to a user or address.
839
+ *
840
+ * @example
841
+ * ```typescript
842
+ * await Channels.email.send({
843
+ * to: { email: 'alice@example.com' },
844
+ * subject: 'Welcome!',
845
+ * html: '<h1>Hello, Alice</h1>',
846
+ * });
847
+ * ```
848
+ */
849
+ send(input: EmailSendInput): Promise<ChannelSendOutput>;
850
+ };
851
+ }
852
+
853
+ export declare type ChannelSendChannel = (typeof CHANNEL_SEND_CHANNELS)[number];
854
+
855
+ /** Body of POST /developer/agents/:agentId/channels/send */
856
+ export declare interface ChannelSendInput {
857
+ channel: ChannelSendChannel;
858
+ to: ChannelSendTarget;
859
+ /** Message text; may contain `::: marker` component blocks — each channel
860
+ * renders them through its existing component pipeline. */
861
+ text: string;
862
+ options?: ChannelSendOptions;
863
+ }
864
+
865
+ export declare interface ChannelSendOptions {
866
+ /** Pin a specific channel config (must belong to the sending agent). */
867
+ channelIdentifier?: string;
868
+ /** WhatsApp-specific send options. */
869
+ whatsapp?: {
870
+ /**
871
+ * Behavior when the 24h customer-service window is CLOSED (PRO-98):
872
+ * - 'queue' (default): send the system message-request template, queue the
873
+ * text, and deliver it once the user replies.
874
+ * - 'fail': reject with a 400 so the caller can send their own approved
875
+ * template via Channels.whatsapp.sendTemplate.
876
+ * Overrides the channel config's `autoMessageRequest` default.
877
+ */
878
+ onClosedWindow?: 'queue' | 'fail';
879
+ };
880
+ }
881
+
882
+ /**
883
+ * Send result. `delivered` and `persisted` are independent: a vendor-accepted
884
+ * send whose memory write failed returns 200 with `persisted: false` plus a
885
+ * `warning` — never an error status for a delivered message.
886
+ */
887
+ export declare interface ChannelSendOutput {
888
+ delivered: boolean;
889
+ persisted: boolean;
890
+ /**
891
+ * True when the send was deferred to the WhatsApp message-request queue
892
+ * because the 24h window was closed (PRO-98). `delivered` is false until the
893
+ * user replies and the queued text flushes; persistence happens at flush.
894
+ */
895
+ queued?: boolean;
896
+ /** Lua userId the message was recorded against (resolved when omitted). */
897
+ userId?: string;
898
+ /** Channel-native recipient identifier actually used (phone, email, PSID…). */
899
+ identifier?: string;
900
+ /** Vendor message id when the channel returns one (e.g. SES MessageId). */
901
+ messageId?: string;
902
+ warning?: string;
903
+ }
904
+
905
+ /** Recipient — exactly one of the fields must be set. userId works on every
906
+ * channel (resolved via the user's channel history); raw identifiers only on
907
+ * cold-start-capable channels (whatsapp/sms → phoneNumber, email → email). */
908
+ export declare interface ChannelSendTarget {
909
+ userId?: string;
910
+ phoneNumber?: string;
911
+ email?: string;
912
+ }
913
+
691
914
  /**
692
915
  * Wire-format types for `GET /chat/history/:agentId` and the VM-sandbox
693
916
  * `User.getChatHistory()` API. Both paths return the same shape.
@@ -700,12 +923,27 @@ export declare type Channel = 'web' | 'whatsapp' | 'facebook' | 'instagram' | 's
700
923
  /**
701
924
  * One content part of a chat-history message.
702
925
  *
703
- * `text` parts carry plain text. Media parts (`image` / `video` / `audio`
704
- * / `file`) carry a URL or base64 payload in `data` (or `image` / `video`
705
- * for legacy reasons) plus a `mediaType` MIME string.
926
+ * `text` parts carry plain text. `reasoning` parts carry the model's
927
+ * chain-of-thought in the `text` field so a history reload can re-render the
928
+ * reasoning component (PRO-391). `tool` parts carry a persisted tool
929
+ * invocation (`toolName`, `toolCallId`, `input` args, and — on a terminal
930
+ * turn — the `output` result and `toolState`) so a reloaded turn can
931
+ * re-render its tool-call cards. `source` parts carry a web-search citation
932
+ * (`url` + optional `title`/`sourceId`) so a reloaded turn keeps its sources
933
+ * footer — the persisted twin of the live stream's `source-url` parts.
934
+ * Media parts (`image` / `video` / `audio` / `file`) carry a URL or base64
935
+ * payload in `data` (or `image` / `video` for legacy reasons) plus a
936
+ * `mediaType` MIME string.
937
+ * `source-url` / `source-document` parts carry a persisted citation
938
+ * (web-search grounding / document citation, PRO-430): `url` + `title` for
939
+ * URLs; `mediaType` + `title` + `filename` (+ citation offsets inside
940
+ * `providerMetadata`) for documents; both keyed by `sourceId`.
941
+ * `data-lua-*` parts carry a persisted enriched stream part (e.g. a
942
+ * sub-agent delegation card) with its original data object in `payload`
943
+ * (`data` is reserved for media payload strings).
706
944
  */
707
945
  export declare interface ChatHistoryContent {
708
- type: 'text' | 'image' | 'video' | 'audio' | 'file';
946
+ type: 'text' | 'reasoning' | 'tool' | 'image' | 'video' | 'audio' | 'file' | 'source-url' | 'source-document' | `data-lua-${string}`;
709
947
  text?: string;
710
948
  image?: string;
711
949
  video?: string;
@@ -713,6 +951,17 @@ export declare interface ChatHistoryContent {
713
951
  mediaType?: string;
714
952
  latitude?: number;
715
953
  longitude?: number;
954
+ toolName?: string;
955
+ toolCallId?: string;
956
+ input?: unknown;
957
+ output?: unknown;
958
+ toolState?: string;
959
+ sourceId?: string;
960
+ url?: string;
961
+ title?: string;
962
+ filename?: string;
963
+ providerMetadata?: Record<string, unknown>;
964
+ payload?: unknown;
716
965
  }
717
966
 
718
967
  /**
@@ -727,6 +976,24 @@ export declare interface ChatHistoryMessage {
727
976
  /** ISO-8601 timestamp string. */
728
977
  createdAt: string;
729
978
  content: ChatHistoryContent[];
979
+ /**
980
+ * Origin of the message, derived from the `mastra_messages.type` column:
981
+ * `'voice'` for turns mirrored from a finished LiveKit voice call, `'chat'`
982
+ * for everything else. Additive/optional — absent on rows written before this
983
+ * landed and on call sites that don't select the `type` column. Clients use it
984
+ * to render a "Voice call" divider in the thread.
985
+ */
986
+ source?: 'voice' | 'chat';
987
+ /**
988
+ * Permanent recording for a voice-note turn (Lua Desktop). Populated by the
989
+ * admin threads history endpoint from the row's `content.metadata.audio` — a
990
+ * sibling of the model content, so the url is NEVER part of the LLM prompt.
991
+ * Present only on desktop voice-note user turns; clients render an audio
992
+ * player / voice bubble off `audio.url`. Absent on all other messages.
993
+ */
994
+ audio?: {
995
+ url: string;
996
+ };
730
997
  }
731
998
 
732
999
  /**
@@ -1017,6 +1284,30 @@ export declare function defineDevice(config: LuaDeviceConfig): LuaDevice;
1017
1284
  */
1018
1285
  export declare function defineDeviceTrigger(config: LuaDeviceTriggerConfig): LuaDeviceTrigger;
1019
1286
 
1287
+ /**
1288
+ * Define an SDK trigger primitive (PRO-95).
1289
+ *
1290
+ * A trigger wakes the agent on an external webhook event with declarative
1291
+ * verify → filter → transform shaping and no `execute`. Compiled, versioned,
1292
+ * and pushed like other code primitives; deploys via `lua push`.
1293
+ *
1294
+ * @example
1295
+ * ```typescript
1296
+ * import { defineTrigger } from 'lua-cli';
1297
+ * import { z } from 'zod';
1298
+ *
1299
+ * export const stripeTrigger = defineTrigger({
1300
+ * name: 'stripe-payments',
1301
+ * description: 'Fires on a successful Stripe payment',
1302
+ * inputSchema: z.object({ type: z.string() }),
1303
+ * verify: (ctx) => verifyStripeSignature(ctx.rawBody, ctx.headers['stripe-signature']),
1304
+ * filter: (ctx) => ctx.body.type === 'payment_intent.succeeded',
1305
+ * transform: (ctx) => `Payment received: ${ctx.body.data.object.amount}`,
1306
+ * });
1307
+ * ```
1308
+ */
1309
+ export declare function defineTrigger<T = any>(config: LuaTriggerConfig<T>): LuaTrigger<T>;
1310
+
1020
1311
  /**
1021
1312
  * Function-style LuaVoice definition. Equivalent to `new LuaVoice(config)`,
1022
1313
  * detected by the compiler via the `defineVoice(...)` AST pattern.
@@ -1085,6 +1376,82 @@ export declare interface DeviceTriggerConfig {
1085
1376
  }) => Promise<any>;
1086
1377
  }
1087
1378
 
1379
+ /** A matched org member and their shareable channel targets (empty when none shared). */
1380
+ export declare interface DirectoryMatch {
1381
+ userId: string;
1382
+ fullName?: string;
1383
+ primaryEmail?: string;
1384
+ targets: DirectoryTarget[];
1385
+ }
1386
+
1387
+ /** Result of POST /developer/agents/:agentId/directory/resolve. */
1388
+ export declare interface DirectoryResolveResult {
1389
+ query: string;
1390
+ matches: DirectoryMatch[];
1391
+ }
1392
+
1393
+ /**
1394
+ * Wire contracts for the workspace directory resolve endpoint.
1395
+ *
1396
+ * lua-cli `Team.findMember(name)` ↔ lua-api `POST /developer/agents/:agentId/directory/resolve`.
1397
+ * Resolves a teammate by name within the AGENT's organization (the org is derived
1398
+ * server-side from the agent), returning only the channel handles each member opted
1399
+ * to share. Returns a list — the caller disambiguates when more than one matches.
1400
+ */
1401
+ /** A channel the teammate opted to be reachable on within the workspace. */
1402
+ export declare interface DirectoryTarget {
1403
+ channel: 'whatsapp' | 'sms' | 'email';
1404
+ /** E.164 for whatsapp/sms; address for email. */
1405
+ value: string;
1406
+ label?: string;
1407
+ validated: boolean;
1408
+ }
1409
+
1410
+ /** A single email attachment, referenced by URL — lua-email fetches the bytes
1411
+ * server-side and attaches them, keeping large files off the SDK→API hops. */
1412
+ declare interface EmailAttachmentInput {
1413
+ filename: string;
1414
+ contentType: string;
1415
+ url: string;
1416
+ }
1417
+
1418
+ /** Body of POST /developer/agents/:agentId/channels/email/send */
1419
+ export declare interface EmailSendInput {
1420
+ /** Recipient — `email` (cold) or `userId` (resolved to the user's email
1421
+ * address from their channel history). At least one must be set. */
1422
+ to: {
1423
+ userId?: string;
1424
+ email?: string;
1425
+ };
1426
+ subject?: string;
1427
+ /** Plain-text body, sent as-is (the MIME text/plain part). */
1428
+ text?: string;
1429
+ /** Exact HTML body, sent as-is (the MIME text/html part) — no template wrap. */
1430
+ html?: string;
1431
+ /**
1432
+ * Rich body — markdown and `:::` component markers, rendered server-side into
1433
+ * the branded email template (the same rendering the agent's own replies use).
1434
+ * Use this for "send this message as a nice email"; use `html` instead when you
1435
+ * want to control the exact markup. Mutually exclusive with `html`/`text`.
1436
+ */
1437
+ richBody?: string;
1438
+ cc?: string[];
1439
+ bcc?: string[];
1440
+ attachments?: EmailAttachmentInput[];
1441
+ /**
1442
+ * RFC 5322 threading: the `Message-ID` of the email this one replies to. Set
1443
+ * `In-Reply-To` (and append to `References`) so mail clients thread the reply
1444
+ * into the right conversation — e.g. a per-ticket thread. The value is the
1445
+ * inbound email's Message-ID, surfaced to agent code as `webhookPayload.messageId`.
1446
+ * Angle brackets are optional; lua-email wraps bare ids. Honoured on the SES
1447
+ * (branded/`existing`) email channel.
1448
+ */
1449
+ inReplyTo?: string;
1450
+ /** RFC 5322 `References` chain — the accumulated Message-IDs of the thread. */
1451
+ references?: string[];
1452
+ options?: ChannelSendOptions;
1453
+ }
1454
+
1088
1455
  /**
1089
1456
  * Safe environment variable access function.
1090
1457
  * Gets injected at runtime with skill-specific environment variables.
@@ -1149,7 +1516,28 @@ declare interface GetJobsResponseData {
1149
1516
  */
1150
1517
  declare interface GovernanceConfig {
1151
1518
  mode: 'sdk' | 'api';
1152
- /** SDK mode — local in-memory policy rules */
1519
+ /**
1520
+ * SDK mode — a named governance-sdk preset composed as the base rule set. The platform builder
1521
+ * maps this to the SDK's preset factories (e.g. `securityBaseline()`), then layers any explicit
1522
+ * `rules`/`injection` on top. `'security'` = block dangerous tools + requireLevel(2).
1523
+ */
1524
+ preset?: 'security';
1525
+ /**
1526
+ * SDK mode — prompt-injection scan on inputs (maps to the SDK's `createInjectionGuard`).
1527
+ * `ml: true` additionally runs the Governance Cloud ML ensemble (regex+DeBERTa) per
1528
+ * message and adds the SDK's `mlInjectionGuard` rule — a hybrid that blocks when EITHER
1529
+ * the regex score crosses `threshold` OR the ML score crosses `mlThreshold`. The two are
1530
+ * scored independently: `threshold` (~0.8) suits the regex weights, while the ML score is
1531
+ * a calibrated model confidence with its own tuned operating point (`mlThreshold`, default
1532
+ * 0.95 — the ensemble's confirmation gate). Requires GOVERNANCE_ML_URL / GOVERNANCE_ML_API_KEY
1533
+ * on the platform; falls back to regex-only when unset or on error.
1534
+ */
1535
+ injection?: {
1536
+ threshold: number;
1537
+ ml?: boolean;
1538
+ mlThreshold?: number;
1539
+ };
1540
+ /** SDK mode — local in-memory policy rules layered on top of any `preset`. */
1153
1541
  rules?: {
1154
1542
  blockTools?: string[];
1155
1543
  requireApproval?: string[];
@@ -1417,7 +1805,7 @@ declare class JobApi extends HttpClient {
1417
1805
  * @returns Promise resolving to an ApiResponse containing the full updated job
1418
1806
  * @throws Error if the job or version is not found or the publish operation fails
1419
1807
  */
1420
- publishJobVersion(jobId: string, version: string): Promise<ApiResponse<Job>>;
1808
+ publishJobVersion(jobId: string, version: string): Promise<ApiResponse<Job & ScopedPromoteFields>>;
1421
1809
  /**
1422
1810
  * Deletes a job and all its versions, or deactivates it if it has versions
1423
1811
  * @param jobId - The unique identifier of the job to delete
@@ -1829,6 +2217,7 @@ export declare class LuaAgent {
1829
2217
  private readonly modelSettings?;
1830
2218
  private readonly skills;
1831
2219
  private readonly webhooks;
2220
+ private readonly triggers;
1832
2221
  private readonly jobs;
1833
2222
  private readonly preProcessors;
1834
2223
  private readonly postProcessors;
@@ -1838,6 +2227,7 @@ export declare class LuaAgent {
1838
2227
  private readonly voices?;
1839
2228
  private readonly batching?;
1840
2229
  private readonly governance?;
2230
+ private readonly browser?;
1841
2231
  /**
1842
2232
  * Creates a new LuaAgent instance.
1843
2233
  *
@@ -1856,11 +2246,14 @@ export declare class LuaAgent {
1856
2246
  */
1857
2247
  constructor(config: LuaAgentConfig);
1858
2248
  getName(): string;
2249
+ /** Browser switch (LuaBrowser) — `true`/config when the agent can browse. */
2250
+ getBrowser(): LuaAgentConfig['browser'];
1859
2251
  getPersona(): PersonaText;
1860
2252
  getModel(): LuaAgentModel | undefined;
1861
2253
  getModelSettings(): AgentModelSettings | undefined;
1862
2254
  getSkills(): LuaSkill[];
1863
2255
  getWebhooks(): LuaWebhook[];
2256
+ getTriggers(): LuaTrigger[];
1864
2257
  getJobs(): LuaJob[];
1865
2258
  getPreProcessors(): PreProcessor[];
1866
2259
  getPostProcessors(): PostProcessor[];
@@ -1882,14 +2275,20 @@ export declare interface LuaAgentConfig {
1882
2275
  * Passed straight through to Mastra / AI SDK on every `chat/stream` and
1883
2276
  * `chat/generate`. Undefined leaves provider defaults in place.
1884
2277
  *
2278
+ * `reasoning` is the exception — it's not a sampling setting. It sets this
2279
+ * agent's default reasoning effort/visibility across providers (Claude,
2280
+ * GPT, Gemini, …); a per-request `options.reasoning` override always wins.
2281
+ *
1885
2282
  * @example
1886
- * modelSettings: { temperature: 0.2, maxOutputTokens: 4096 }
2283
+ * modelSettings: { temperature: 0.2, maxOutputTokens: 4096, reasoning: { effort: 'low' } }
1887
2284
  */
1888
2285
  modelSettings?: AgentModelSettings;
1889
2286
  /** Array of skills (each with tools) */
1890
2287
  skills?: LuaSkill[];
1891
2288
  /** Array of webhooks */
1892
2289
  webhooks?: LuaWebhook[];
2290
+ /** Array of SDK triggers (defineTrigger) — wake the agent on external events with verify/filter/transform */
2291
+ triggers?: LuaTrigger[];
1893
2292
  /** Array of scheduled jobs */
1894
2293
  jobs?: LuaJob[];
1895
2294
  /** Array of preprocessors (run before messages reach the agent) */
@@ -1913,6 +2312,13 @@ export declare interface LuaAgentConfig {
1913
2312
  batching?: BatchingConfig;
1914
2313
  /** Governance policy configuration. When set, tool calls, preprocessors, and postprocessors are governed. */
1915
2314
  governance?: GovernanceConfig;
2315
+ /**
2316
+ * Browser switch (LuaBrowser). `true` turns on browser tools with platform
2317
+ * defaults; an object adds policy (engine, allowedDomains, credentials,
2318
+ * maxSessionMinutes). Off by default — a browser session costs money and
2319
+ * carries risk, so it's opt-in (unlike always-on searchWeb).
2320
+ */
2321
+ browser?: boolean | BrowserSwitchConfig;
1916
2322
  }
1917
2323
 
1918
2324
  /**
@@ -2417,6 +2823,74 @@ declare interface LuaToolCtx {
2417
2823
  };
2418
2824
  }
2419
2825
 
2826
+ /**
2827
+ * Lua Trigger class (PRO-95). Wakes an agent on an external webhook event with
2828
+ * declarative verify → filter → transform shaping and no `execute`.
2829
+ *
2830
+ * @example
2831
+ * ```typescript
2832
+ * import { LuaTrigger } from 'lua-cli';
2833
+ * import { z } from 'zod';
2834
+ *
2835
+ * export default new LuaTrigger({
2836
+ * name: 'stripe-payments',
2837
+ * description: 'Fires on a successful Stripe payment',
2838
+ * inputSchema: z.object({ type: z.string() }),
2839
+ * verify: (ctx) => verifyStripeSignature(ctx.rawBody, ctx.headers['stripe-signature']),
2840
+ * filter: (ctx) => ctx.body.type === 'payment_intent.succeeded',
2841
+ * transform: (ctx) => `Payment received: ${ctx.body.data.object.amount}`,
2842
+ * });
2843
+ * ```
2844
+ */
2845
+ export declare class LuaTrigger<T = any> {
2846
+ readonly name: string;
2847
+ readonly description: string;
2848
+ readonly source: 'webhook';
2849
+ readonly inputSchema?: ZodType;
2850
+ readonly verify?: (ctx: TriggerContext<T>) => boolean | Promise<boolean>;
2851
+ readonly filter?: (ctx: TriggerContext<T>) => boolean | Promise<boolean>;
2852
+ readonly transform?: (ctx: TriggerContext<T>) => string | AgentInvocationInput | Promise<string | AgentInvocationInput>;
2853
+ constructor(config: LuaTriggerConfig<T>);
2854
+ getName(): string;
2855
+ getDescription(): string;
2856
+ }
2857
+
2858
+ /**
2859
+ * Lua Trigger configuration (PRO-95).
2860
+ *
2861
+ * A trigger wakes an agent on an external event with declarative shaping. It has
2862
+ * NO `execute` function — that's the defining feature. The only customization
2863
+ * surface is the three optional slots, run server-side per request:
2864
+ * - `verify` — false ⇒ HTTP 401, no invocation (put HMAC checks here)
2865
+ * - `filter` — false ⇒ HTTP 200, no invocation (intentionally ignore the event)
2866
+ * - `transform` — shapes the agent input; default is `body → message`
2867
+ *
2868
+ * For full request/response control (a custom HTTP response, side effects),
2869
+ * reach for `LuaWebhook` instead.
2870
+ */
2871
+ export declare interface LuaTriggerConfig<T = any> {
2872
+ /** Trigger name (required; used as the server-side identifier). */
2873
+ name: string;
2874
+ /** Short description (a dashboard note; NOT sent to the agent). */
2875
+ description: string;
2876
+ /** Event source discriminator. Only 'webhook' in v1; 'cron'/'event' are future. */
2877
+ source?: 'webhook';
2878
+ /** Optional Zod schema for the event body (types `ctx.body`). */
2879
+ inputSchema?: ZodType;
2880
+ /** Reject the event with HTTP 401 when this returns false. */
2881
+ verify?: (ctx: TriggerContext<T>) => boolean | Promise<boolean>;
2882
+ /** Skip invocation (HTTP 200, no agent run) when this returns false. */
2883
+ filter?: (ctx: TriggerContext<T>) => boolean | Promise<boolean>;
2884
+ /**
2885
+ * Shape the agent input. Return a `string` (the message) or a full
2886
+ * `AgentInvocationInput` (you own the turn). Returning null/undefined is an
2887
+ * error — use `filter` to skip. Omit to use the default `body → message`,
2888
+ * whose payload is capped at ~50k chars (like a no-code trigger); return a
2889
+ * transform to forward larger or hand-picked fields as the message.
2890
+ */
2891
+ transform?: (ctx: TriggerContext<T>) => string | AgentInvocationInput | Promise<string | AgentInvocationInput>;
2892
+ }
2893
+
2420
2894
  /**
2421
2895
  * Code-defined voice agent. Pushed via `lua push`, attached to channels through
2422
2896
  * the owning `LuaAgent.voice` field. Auto-dispatched into LiveKit rooms when a
@@ -2466,6 +2940,7 @@ export declare class LuaVoice {
2466
2940
  readonly preemptiveGeneration: LuaVoiceConfig_2['preemptiveGeneration'];
2467
2941
  readonly interruption: LuaVoiceConfig_2['interruption'];
2468
2942
  readonly sttLanguage: LuaVoiceConfig_2['sttLanguage'];
2943
+ readonly excludeTools: LuaVoiceConfig_2['excludeTools'];
2469
2944
  readonly tools: ReadonlyArray<LuaTool<any> | LuaVoiceTool<any>>;
2470
2945
  readonly onEnter?: LuaVoiceConfig['onEnter'];
2471
2946
  readonly onUserTurnCompleted?: LuaVoiceConfig['onUserTurnCompleted'];
@@ -2574,11 +3049,11 @@ declare const LuaVoiceConfigSchema: z.ZodEffects<z.ZodObject<{
2574
3049
  }, "strip", z.ZodTypeAny, {
2575
3050
  options?: Record<string, unknown>;
2576
3051
  kind?: "realtime";
2577
- provider?: "openai" | "google" | "xai";
3052
+ provider?: "google" | "xai" | "openai";
2578
3053
  }, {
2579
3054
  options?: Record<string, unknown>;
2580
3055
  kind?: "realtime";
2581
- provider?: "openai" | "google" | "xai";
3056
+ provider?: "google" | "xai" | "openai";
2582
3057
  }>]>;
2583
3058
  stt: z.ZodOptional<z.ZodDiscriminatedUnion<"kind", [z.ZodObject<{
2584
3059
  kind: z.ZodLiteral<"inference">;
@@ -2640,11 +3115,11 @@ declare const LuaVoiceConfigSchema: z.ZodEffects<z.ZodObject<{
2640
3115
  }, "strip", z.ZodTypeAny, {
2641
3116
  options?: Record<string, unknown>;
2642
3117
  kind?: "realtime";
2643
- provider?: "openai" | "google" | "xai";
3118
+ provider?: "google" | "xai" | "openai";
2644
3119
  }, {
2645
3120
  options?: Record<string, unknown>;
2646
3121
  kind?: "realtime";
2647
- provider?: "openai" | "google" | "xai";
3122
+ provider?: "google" | "xai" | "openai";
2648
3123
  }>]>>;
2649
3124
  tts: z.ZodOptional<z.ZodDiscriminatedUnion<"kind", [z.ZodObject<{
2650
3125
  kind: z.ZodLiteral<"inference">;
@@ -2706,11 +3181,11 @@ declare const LuaVoiceConfigSchema: z.ZodEffects<z.ZodObject<{
2706
3181
  }, "strip", z.ZodTypeAny, {
2707
3182
  options?: Record<string, unknown>;
2708
3183
  kind?: "realtime";
2709
- provider?: "openai" | "google" | "xai";
3184
+ provider?: "google" | "xai" | "openai";
2710
3185
  }, {
2711
3186
  options?: Record<string, unknown>;
2712
3187
  kind?: "realtime";
2713
- provider?: "openai" | "google" | "xai";
3188
+ provider?: "google" | "xai" | "openai";
2714
3189
  }>]>>;
2715
3190
  vad: z.ZodOptional<z.ZodString>;
2716
3191
  vadOptions: z.ZodOptional<z.ZodObject<{
@@ -2743,28 +3218,28 @@ declare const LuaVoiceConfigSchema: z.ZodEffects<z.ZodObject<{
2743
3218
  maxDelay: z.ZodOptional<z.ZodNumber>;
2744
3219
  }, "strip", z.ZodTypeAny, {
2745
3220
  enabled?: boolean;
2746
- mode?: "vad" | "adaptive";
3221
+ mode?: "adaptive" | "vad";
2747
3222
  falseInterruptionTimeout?: number;
2748
3223
  resumeFalseInterruption?: boolean;
2749
3224
  minDelay?: number;
2750
3225
  maxDelay?: number;
2751
3226
  }, {
2752
3227
  enabled?: boolean;
2753
- mode?: "vad" | "adaptive";
3228
+ mode?: "adaptive" | "vad";
2754
3229
  falseInterruptionTimeout?: number;
2755
3230
  resumeFalseInterruption?: boolean;
2756
3231
  minDelay?: number;
2757
3232
  maxDelay?: number;
2758
3233
  }>, {
2759
3234
  enabled?: boolean;
2760
- mode?: "vad" | "adaptive";
3235
+ mode?: "adaptive" | "vad";
2761
3236
  falseInterruptionTimeout?: number;
2762
3237
  resumeFalseInterruption?: boolean;
2763
3238
  minDelay?: number;
2764
3239
  maxDelay?: number;
2765
3240
  }, {
2766
3241
  enabled?: boolean;
2767
- mode?: "vad" | "adaptive";
3242
+ mode?: "adaptive" | "vad";
2768
3243
  falseInterruptionTimeout?: number;
2769
3244
  resumeFalseInterruption?: boolean;
2770
3245
  minDelay?: number;
@@ -2866,7 +3341,9 @@ declare const LuaVoiceConfigSchema: z.ZodEffects<z.ZodObject<{
2866
3341
  pronunciations: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
2867
3342
  persistTranscript: z.ZodOptional<z.ZodBoolean>;
2868
3343
  onToolFailureSay: z.ZodOptional<z.ZodString>;
3344
+ excludeTools: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
2869
3345
  }, "strip", z.ZodTypeAny, {
3346
+ name?: string;
2870
3347
  vad?: string;
2871
3348
  stt?: {
2872
3349
  voice?: string;
@@ -2881,10 +3358,9 @@ declare const LuaVoiceConfigSchema: z.ZodEffects<z.ZodObject<{
2881
3358
  } | {
2882
3359
  options?: Record<string, unknown>;
2883
3360
  kind?: "realtime";
2884
- provider?: "openai" | "google" | "xai";
3361
+ provider?: "google" | "xai" | "openai";
2885
3362
  };
2886
3363
  volume?: number;
2887
- name?: string;
2888
3364
  llm?: {
2889
3365
  voice?: string;
2890
3366
  options?: Record<string, unknown>;
@@ -2898,7 +3374,7 @@ declare const LuaVoiceConfigSchema: z.ZodEffects<z.ZodObject<{
2898
3374
  } | {
2899
3375
  options?: Record<string, unknown>;
2900
3376
  kind?: "realtime";
2901
- provider?: "openai" | "google" | "xai";
3377
+ provider?: "google" | "xai" | "openai";
2902
3378
  };
2903
3379
  tts?: {
2904
3380
  voice?: string;
@@ -2913,7 +3389,7 @@ declare const LuaVoiceConfigSchema: z.ZodEffects<z.ZodObject<{
2913
3389
  } | {
2914
3390
  options?: Record<string, unknown>;
2915
3391
  kind?: "realtime";
2916
- provider?: "openai" | "google" | "xai";
3392
+ provider?: "google" | "xai" | "openai";
2917
3393
  };
2918
3394
  vadOptions?: {
2919
3395
  minSpeechDuration?: number;
@@ -2928,7 +3404,7 @@ declare const LuaVoiceConfigSchema: z.ZodEffects<z.ZodObject<{
2928
3404
  preemptiveGeneration?: boolean;
2929
3405
  interruption?: {
2930
3406
  enabled?: boolean;
2931
- mode?: "vad" | "adaptive";
3407
+ mode?: "adaptive" | "vad";
2932
3408
  falseInterruptionTimeout?: number;
2933
3409
  resumeFalseInterruption?: boolean;
2934
3410
  minDelay?: number;
@@ -2959,7 +3435,9 @@ declare const LuaVoiceConfigSchema: z.ZodEffects<z.ZodObject<{
2959
3435
  pronunciations?: Record<string, string>;
2960
3436
  persistTranscript?: boolean;
2961
3437
  onToolFailureSay?: string;
3438
+ excludeTools?: string[];
2962
3439
  }, {
3440
+ name?: string;
2963
3441
  vad?: string;
2964
3442
  stt?: {
2965
3443
  voice?: string;
@@ -2974,10 +3452,9 @@ declare const LuaVoiceConfigSchema: z.ZodEffects<z.ZodObject<{
2974
3452
  } | {
2975
3453
  options?: Record<string, unknown>;
2976
3454
  kind?: "realtime";
2977
- provider?: "openai" | "google" | "xai";
3455
+ provider?: "google" | "xai" | "openai";
2978
3456
  };
2979
3457
  volume?: number;
2980
- name?: string;
2981
3458
  llm?: {
2982
3459
  voice?: string;
2983
3460
  options?: Record<string, unknown>;
@@ -2991,7 +3468,7 @@ declare const LuaVoiceConfigSchema: z.ZodEffects<z.ZodObject<{
2991
3468
  } | {
2992
3469
  options?: Record<string, unknown>;
2993
3470
  kind?: "realtime";
2994
- provider?: "openai" | "google" | "xai";
3471
+ provider?: "google" | "xai" | "openai";
2995
3472
  };
2996
3473
  tts?: {
2997
3474
  voice?: string;
@@ -3006,7 +3483,7 @@ declare const LuaVoiceConfigSchema: z.ZodEffects<z.ZodObject<{
3006
3483
  } | {
3007
3484
  options?: Record<string, unknown>;
3008
3485
  kind?: "realtime";
3009
- provider?: "openai" | "google" | "xai";
3486
+ provider?: "google" | "xai" | "openai";
3010
3487
  };
3011
3488
  vadOptions?: {
3012
3489
  minSpeechDuration?: number;
@@ -3021,7 +3498,7 @@ declare const LuaVoiceConfigSchema: z.ZodEffects<z.ZodObject<{
3021
3498
  preemptiveGeneration?: boolean;
3022
3499
  interruption?: {
3023
3500
  enabled?: boolean;
3024
- mode?: "vad" | "adaptive";
3501
+ mode?: "adaptive" | "vad";
3025
3502
  falseInterruptionTimeout?: number;
3026
3503
  resumeFalseInterruption?: boolean;
3027
3504
  minDelay?: number;
@@ -3052,7 +3529,9 @@ declare const LuaVoiceConfigSchema: z.ZodEffects<z.ZodObject<{
3052
3529
  pronunciations?: Record<string, string>;
3053
3530
  persistTranscript?: boolean;
3054
3531
  onToolFailureSay?: string;
3532
+ excludeTools?: string[];
3055
3533
  }>, {
3534
+ name?: string;
3056
3535
  vad?: string;
3057
3536
  stt?: {
3058
3537
  voice?: string;
@@ -3067,10 +3546,9 @@ declare const LuaVoiceConfigSchema: z.ZodEffects<z.ZodObject<{
3067
3546
  } | {
3068
3547
  options?: Record<string, unknown>;
3069
3548
  kind?: "realtime";
3070
- provider?: "openai" | "google" | "xai";
3549
+ provider?: "google" | "xai" | "openai";
3071
3550
  };
3072
3551
  volume?: number;
3073
- name?: string;
3074
3552
  llm?: {
3075
3553
  voice?: string;
3076
3554
  options?: Record<string, unknown>;
@@ -3084,7 +3562,7 @@ declare const LuaVoiceConfigSchema: z.ZodEffects<z.ZodObject<{
3084
3562
  } | {
3085
3563
  options?: Record<string, unknown>;
3086
3564
  kind?: "realtime";
3087
- provider?: "openai" | "google" | "xai";
3565
+ provider?: "google" | "xai" | "openai";
3088
3566
  };
3089
3567
  tts?: {
3090
3568
  voice?: string;
@@ -3099,7 +3577,7 @@ declare const LuaVoiceConfigSchema: z.ZodEffects<z.ZodObject<{
3099
3577
  } | {
3100
3578
  options?: Record<string, unknown>;
3101
3579
  kind?: "realtime";
3102
- provider?: "openai" | "google" | "xai";
3580
+ provider?: "google" | "xai" | "openai";
3103
3581
  };
3104
3582
  vadOptions?: {
3105
3583
  minSpeechDuration?: number;
@@ -3114,7 +3592,7 @@ declare const LuaVoiceConfigSchema: z.ZodEffects<z.ZodObject<{
3114
3592
  preemptiveGeneration?: boolean;
3115
3593
  interruption?: {
3116
3594
  enabled?: boolean;
3117
- mode?: "vad" | "adaptive";
3595
+ mode?: "adaptive" | "vad";
3118
3596
  falseInterruptionTimeout?: number;
3119
3597
  resumeFalseInterruption?: boolean;
3120
3598
  minDelay?: number;
@@ -3145,7 +3623,9 @@ declare const LuaVoiceConfigSchema: z.ZodEffects<z.ZodObject<{
3145
3623
  pronunciations?: Record<string, string>;
3146
3624
  persistTranscript?: boolean;
3147
3625
  onToolFailureSay?: string;
3626
+ excludeTools?: string[];
3148
3627
  }, {
3628
+ name?: string;
3149
3629
  vad?: string;
3150
3630
  stt?: {
3151
3631
  voice?: string;
@@ -3160,10 +3640,9 @@ declare const LuaVoiceConfigSchema: z.ZodEffects<z.ZodObject<{
3160
3640
  } | {
3161
3641
  options?: Record<string, unknown>;
3162
3642
  kind?: "realtime";
3163
- provider?: "openai" | "google" | "xai";
3643
+ provider?: "google" | "xai" | "openai";
3164
3644
  };
3165
3645
  volume?: number;
3166
- name?: string;
3167
3646
  llm?: {
3168
3647
  voice?: string;
3169
3648
  options?: Record<string, unknown>;
@@ -3177,7 +3656,7 @@ declare const LuaVoiceConfigSchema: z.ZodEffects<z.ZodObject<{
3177
3656
  } | {
3178
3657
  options?: Record<string, unknown>;
3179
3658
  kind?: "realtime";
3180
- provider?: "openai" | "google" | "xai";
3659
+ provider?: "google" | "xai" | "openai";
3181
3660
  };
3182
3661
  tts?: {
3183
3662
  voice?: string;
@@ -3192,7 +3671,7 @@ declare const LuaVoiceConfigSchema: z.ZodEffects<z.ZodObject<{
3192
3671
  } | {
3193
3672
  options?: Record<string, unknown>;
3194
3673
  kind?: "realtime";
3195
- provider?: "openai" | "google" | "xai";
3674
+ provider?: "google" | "xai" | "openai";
3196
3675
  };
3197
3676
  vadOptions?: {
3198
3677
  minSpeechDuration?: number;
@@ -3207,7 +3686,7 @@ declare const LuaVoiceConfigSchema: z.ZodEffects<z.ZodObject<{
3207
3686
  preemptiveGeneration?: boolean;
3208
3687
  interruption?: {
3209
3688
  enabled?: boolean;
3210
- mode?: "vad" | "adaptive";
3689
+ mode?: "adaptive" | "vad";
3211
3690
  falseInterruptionTimeout?: number;
3212
3691
  resumeFalseInterruption?: boolean;
3213
3692
  minDelay?: number;
@@ -3238,6 +3717,7 @@ declare const LuaVoiceConfigSchema: z.ZodEffects<z.ZodObject<{
3238
3717
  pronunciations?: Record<string, string>;
3239
3718
  persistTranscript?: boolean;
3240
3719
  onToolFailureSay?: string;
3720
+ excludeTools?: string[];
3241
3721
  }>;
3242
3722
 
3243
3723
  /**
@@ -3311,10 +3791,10 @@ export declare interface LuaVoiceToolConfig<TInput extends ZodType = ZodType> {
3311
3791
  * its second `execute` arg whether it runs over chat or voice; this
3312
3792
  * extension just adds the Phase-5 fields (currently optional + experimental).
3313
3793
  *
3314
- * `say()` is wired today and delegates to the active LiveKit `voice.AgentSession`.
3315
- * `disallowInterruptions()` and `handoff()` are optional placeholders for
3316
- * Phase 5 (BAC-213, the LuaVoice handoffs + test framework ticket).
3317
- * Marked optional both because they aren't implemented yet AND so this
3794
+ * `say()`, `transferToHuman()`, `endCall()` and `handoff()` are wired today
3795
+ * and delegate to the active LiveKit `voice.AgentSession`.
3796
+ * `disallowInterruptions()` is an optional placeholder the barge-in lock
3797
+ * plumbing isn't implemented yet. The delegates are marked optional so this
3318
3798
  * type stays structurally compatible with `LuaToolCtx` — that
3319
3799
  * compatibility is what lets a `LuaVoiceTool` (which extends `LuaTool`)
3320
3800
  * present `(ctx?: LuaVoiceToolCtx)` while satisfying the parent's
@@ -3376,9 +3856,24 @@ export declare interface LuaVoiceToolCtx {
3376
3856
  */
3377
3857
  disallowInterruptions?(): void;
3378
3858
  /**
3379
- * @experimental Reserved for Phase 5 (BAC-213). Optional because
3380
- * unimplemented handoffs require `chatCtx.copy(exclude_instructions=True)`
3381
- * + `update_agent` plumbing that's part of the multi-LuaVoice flow ticket.
3859
+ * Hand the live call to another LuaVoice on the same agent,
3860
+ * addressed by its `name`. The caller stays in the same room; only
3861
+ * the agent identity flips the receiving voice starts cold from
3862
+ * its own persona + greeting (no conversation history carries
3863
+ * over). Pass `context` to surface a structured payload to the
3864
+ * receiving voice on its first turn.
3865
+ *
3866
+ * In `lua voice test`, register reachable voices via
3867
+ * `runVoice({ handoffTargets })`; in production, any voice pushed
3868
+ * on the same agent is reachable. An unknown name degrades
3869
+ * in-call (spoken fallback, no crash).
3870
+ *
3871
+ * @example
3872
+ * ```typescript
3873
+ * await ctx.voice?.handoff('billing-line', {
3874
+ * context: { reason: 'invoice question', orderId: input.orderId },
3875
+ * });
3876
+ * ```
3382
3877
  */
3383
3878
  handoff?(otherVoiceName: string, opts?: {
3384
3879
  context?: Record<string, unknown>;
@@ -4484,6 +4979,29 @@ declare interface PushJobVersionDTO {
4484
4979
  metadata?: Record<string, any>;
4485
4980
  }
4486
4981
 
4982
+ /**
4983
+ * Normalized, provider-agnostic model request options.
4984
+ *
4985
+ * This is the shape clients (Lua Desktop, lua-cli, admin overrides) use to
4986
+ * ask for a reasoning effort / output verbosity without knowing which
4987
+ * provider dialect (Anthropic `thinking`, OpenAI `reasoningEffort`, Google
4988
+ * `thinkingConfig`, …) the resolved model actually speaks. lua-core's
4989
+ * `buildProviderOptions` translates this into the wire-level
4990
+ * `providerOptions` shape per model.
4991
+ */
4992
+ declare const REASONING_EFFORT_VALUES: readonly ["off", "minimal", "low", "medium", "high", "max"];
4993
+
4994
+ declare type ReasoningEffort = (typeof REASONING_EFFORT_VALUES)[number];
4995
+
4996
+ /**
4997
+ * Additive field on primitive publish responses. When the agent is under
4998
+ * versioning the server performs a scoped promote and returns the newly
4999
+ * minted + promoted agent version here; absent when the agent has no versions.
5000
+ */
5001
+ declare interface ScopedPromoteFields {
5002
+ agentVersion?: number;
5003
+ }
5004
+
4487
5005
  /**
4488
5006
  * Response from product search.
4489
5007
  */
@@ -4534,6 +5052,33 @@ declare type SkillContextText = string | {
4534
5052
  text?: string;
4535
5053
  };
4536
5054
 
5055
+ export declare const Team: TeamApi;
5056
+
5057
+ /**
5058
+ * Team API — resolve a teammate by name within the agent's organization and get
5059
+ * the channel handles they opted to share. Pair with `Channels.send` to message a
5060
+ * colleague without typing their number.
5061
+ *
5062
+ * The org is derived server-side from the agent; you can only resolve members of
5063
+ * your own org. Returns a list — disambiguate when more than one member matches.
5064
+ *
5065
+ * @example
5066
+ * ```typescript
5067
+ * const { matches } = await Team.findMember('Stefan');
5068
+ * const wa = matches[0]?.targets.find((t) => t.channel === 'whatsapp');
5069
+ * if (wa) {
5070
+ * await Channels.send({ channel: 'whatsapp', to: { phoneNumber: wa.value }, text: 'Hi Stefan!' });
5071
+ * }
5072
+ * ```
5073
+ */
5074
+ export declare interface TeamApi {
5075
+ /**
5076
+ * Resolve teammates whose name matches, each with their shareable channel
5077
+ * targets (empty `targets[]` when the member shared nothing).
5078
+ */
5079
+ findMember(name: string): Promise<DirectoryResolveResult>;
5080
+ }
5081
+
4537
5082
  /**
4538
5083
  * Templates API
4539
5084
  *
@@ -4689,6 +5234,30 @@ export declare enum ToolFlag {
4689
5234
  DISALLOW_INTERRUPTION = "disallow_interruption"
4690
5235
  }
4691
5236
 
5237
+ /**
5238
+ * Context delivered to a trigger's verify / filter / transform slots.
5239
+ *
5240
+ * Unlike a webhook event, `rawBody` carries the EXACT unparsed request bytes
5241
+ * (utf8) — HMAC signature schemes (Stripe `t=…,v1=…`, GitHub `sha256=…`, Slack
5242
+ * `v0:…`) are computed over the wire bytes, which `JSON.stringify(body)` does
5243
+ * not reproduce. `headers` keys arrive lowercased (Express), e.g.
5244
+ * `ctx.headers['x-hub-signature-256']`.
5245
+ */
5246
+ export declare interface TriggerContext<T = any> {
5247
+ /** Parsed request body (typed by `inputSchema` when provided). */
5248
+ body: T;
5249
+ /** Exact unparsed request bytes as a utf8 string — for HMAC signature checks. */
5250
+ rawBody?: string;
5251
+ /** Request headers (lowercased keys). */
5252
+ headers: Record<string, any>;
5253
+ /** Parsed query-string parameters. */
5254
+ query: Record<string, any>;
5255
+ /** This trigger's name. */
5256
+ triggerName: string;
5257
+ /** Event source discriminator ('webhook' in v1). */
5258
+ source: string;
5259
+ }
5260
+
4692
5261
  /**
4693
5262
  * Response from updating custom data entry.
4694
5263
  */
@@ -4916,6 +5485,18 @@ export declare interface VoiceApi {
4916
5485
  * ```
4917
5486
  */
4918
5487
  call(input: VoiceDispatchInput): Promise<VoiceDispatchOutput>;
5488
+ /**
5489
+ * Create a voice room + client access token for your own frontend
5490
+ * (standard livekit-client). The session runs under a synthetic identity;
5491
+ * pass `userId` to scope conversation memory + transcript to your end user.
5492
+ *
5493
+ * @example
5494
+ * ```typescript
5495
+ * const { url, roomName, token } = await Voice.createSession({ userId: 'u-42' });
5496
+ * // hand url + token to livekit-client's room.connect(url, token)
5497
+ * ```
5498
+ */
5499
+ createSession(input?: VoiceSessionInput): Promise<VoiceSessionOutput>;
4919
5500
  }
4920
5501
 
4921
5502
  /**
@@ -5027,6 +5608,28 @@ string | {
5027
5608
  returnToken?: boolean;
5028
5609
  };
5029
5610
 
5611
+ /** Input for creating a developer voice room (custom frontend). */
5612
+ declare interface VoiceSessionInput {
5613
+ /** Voice channel for the session. Defaults to 'web'. */
5614
+ channel?: string;
5615
+ /** External end-user id, for conversation-memory + transcript scoping. */
5616
+ userId?: string;
5617
+ /** LuaVoice id to run, overriding the agent's channel-bound voice. */
5618
+ voiceId?: string;
5619
+ displayName?: string;
5620
+ }
5621
+
5622
+ /** Room + client token a livekit-client frontend connects with. */
5623
+ declare interface VoiceSessionOutput {
5624
+ /** LiveKit server URL (wss://). */
5625
+ url: string;
5626
+ roomName: string;
5627
+ /** Client access token (LiveKit AccessToken JWT). */
5628
+ token: string;
5629
+ participantIdentity: string;
5630
+ agentName: string;
5631
+ }
5632
+
5030
5633
  /**
5031
5634
  * Webhook request information from channel integrations.
5032
5635
  * Contains the raw webhook payload from the channel provider.
@@ -5036,6 +5639,20 @@ export declare interface WebhookRequest {
5036
5639
  payload: any;
5037
5640
  }
5038
5641
 
5642
+ /** Body of POST /developer/agents/:agentId/channels/whatsapp/reaction */
5643
+ export declare interface WhatsAppReactionSendInput {
5644
+ to: {
5645
+ userId?: string;
5646
+ phoneNumber?: string;
5647
+ };
5648
+ /** Vendor id (`wamid...`) of the message to react to — e.g. an inbound
5649
+ * message's id from the conversation history, ≤30 days old per Meta. */
5650
+ messageId: string;
5651
+ /** A single emoji. An empty string removes the agent's existing reaction. */
5652
+ emoji: string;
5653
+ options?: ChannelSendOptions;
5654
+ }
5655
+
5039
5656
  export declare interface WhatsAppTemplate {
5040
5657
  id: string;
5041
5658
  name: string;
@@ -5112,6 +5729,21 @@ declare interface WhatsAppTemplateQuickReplyButton {
5112
5729
  text: string;
5113
5730
  }
5114
5731
 
5732
+ /** Body of POST /developer/agents/:agentId/channels/whatsapp/template */
5733
+ export declare interface WhatsAppTemplateSendInput {
5734
+ to: {
5735
+ userId?: string;
5736
+ phoneNumber?: string;
5737
+ };
5738
+ templateName: string;
5739
+ languageCode?: string;
5740
+ /** Meta template components (header/body/buttons parameter values). */
5741
+ components?: Array<Record<string, unknown>>;
5742
+ /** Text persisted to the agent's memory as what this template said. */
5743
+ messageContext?: string;
5744
+ options?: ChannelSendOptions;
5745
+ }
5746
+
5115
5747
  export declare type WhatsAppTemplateStatus = 'APPROVED' | 'REJECTED' | 'PENDING';
5116
5748
 
5117
5749
  declare interface WhatsAppTemplateUrlButton {