lua-cli 3.16.2 → 3.17.1

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.
@@ -78,6 +78,36 @@ declare interface AgentInvocationOutput {
78
78
  threadId?: string;
79
79
  }
80
80
 
81
+ /**
82
+ * Per-agent LLM call settings. Maps directly onto Mastra's
83
+ * `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).
87
+ *
88
+ * Deliberately excludes `abortSignal` (not serializable), `headers`
89
+ * (security — could exfiltrate credentials), and `maxRetries` (platform
90
+ * concern, not customer-tunable).
91
+ */
92
+ declare interface AgentModelSettings {
93
+ /** Sampling temperature. Range depends on provider (typically 0..2 for Anthropic/OpenAI). */
94
+ temperature?: number;
95
+ /** Nucleus sampling. 0..1. Recommended: set either `temperature` or `topP`, not both. */
96
+ topP?: number;
97
+ /** Top-K sampling. Advanced. */
98
+ topK?: number;
99
+ /** Maximum tokens to generate. */
100
+ maxOutputTokens?: number;
101
+ /** Presence penalty. -2..2 (OpenAI); not all providers support. */
102
+ presencePenalty?: number;
103
+ /** Frequency penalty. -2..2 (OpenAI); not all providers support. */
104
+ frequencyPenalty?: number;
105
+ /** Stop sequences. Generation halts when the model emits one of these. */
106
+ stopSequences?: string[];
107
+ /** Random seed for deterministic sampling (provider support varies). */
108
+ seed?: number;
109
+ }
110
+
81
111
  export declare const Agents: AgentsApi;
82
112
 
83
113
  /**
@@ -165,8 +195,21 @@ declare interface AiGenerateInput {
165
195
  messages?: unknown[];
166
196
  temperature?: number;
167
197
  maxOutputTokens?: number;
198
+ /**
199
+ * When set, constrains the response to match the JSON Schema. The parsed result
200
+ * lands on `AiGenerateOutput.output`. Mirrors AI SDK `Output.object({ schema })`.
201
+ * Object-mode only in this version — array/choice modes are future extensions.
202
+ */
203
+ structuredOutput?: AiGenerateStructuredOutput;
168
204
  }
169
205
 
206
+ /**
207
+ * JSON Schema 7-shaped object describing the structured output the model must return.
208
+ * Kept as `Record<string, unknown>` to avoid pulling `@types/json-schema` into the
209
+ * published lua-cli surface; callers typically produce this via `zodToJsonSchema`.
210
+ */
211
+ declare type AiGenerateJsonSchema = Record<string, unknown>;
212
+
170
213
  /**
171
214
  * Wire-format output from `AI.generate` / `POST .../generate`.
172
215
  * Fields mirror AI SDK `GenerateTextResult` — uses AI SDK types where exported.
@@ -188,6 +231,11 @@ declare interface AiGenerateOutput {
188
231
  toolCalls?: AiGenerateToolCall[];
189
232
  /** Tool results from generation */
190
233
  toolResults?: AiGenerateToolResult[];
234
+ /**
235
+ * Parsed structured result when `AiGenerateInput.structuredOutput` was set.
236
+ * Shape conforms to the supplied JSON Schema. Mirrors AI SDK `result.output`.
237
+ */
238
+ output?: unknown;
191
239
  /** Provider warnings (e.g. unsupported settings) — AI SDK `CallWarning[]` */
192
240
  warnings?: CallWarning[];
193
241
  }
@@ -203,6 +251,15 @@ declare interface AiGenerateSource {
203
251
  title?: string;
204
252
  }
205
253
 
254
+ /**
255
+ * Structured-output spec. Maps to AI SDK `output: Output.object({ schema })` on `generateText`.
256
+ * Result lands on `AiGenerateOutput.output`.
257
+ */
258
+ declare interface AiGenerateStructuredOutput {
259
+ /** JSON Schema 7 describing the expected object shape. */
260
+ schema: AiGenerateJsonSchema;
261
+ }
262
+
206
263
  /**
207
264
  * Serializable tool call. Mirrors `TypedToolCall` without generics.
208
265
  * `input` matches the AI SDK field name (renamed from `args` in v5).
@@ -255,6 +312,7 @@ declare interface ApiResponse<T = any> {
255
312
  data?: T;
256
313
  error?: {
257
314
  message: string;
315
+ code?: string;
258
316
  statusCode?: number;
259
317
  error?: string;
260
318
  };
@@ -1768,6 +1826,7 @@ export declare class LuaAgent {
1768
1826
  private readonly name;
1769
1827
  private readonly persona;
1770
1828
  private readonly model?;
1829
+ private readonly modelSettings?;
1771
1830
  private readonly skills;
1772
1831
  private readonly webhooks;
1773
1832
  private readonly jobs;
@@ -1799,6 +1858,7 @@ export declare class LuaAgent {
1799
1858
  getName(): string;
1800
1859
  getPersona(): PersonaText;
1801
1860
  getModel(): LuaAgentModel | undefined;
1861
+ getModelSettings(): AgentModelSettings | undefined;
1802
1862
  getSkills(): LuaSkill[];
1803
1863
  getWebhooks(): LuaWebhook[];
1804
1864
  getJobs(): LuaJob[];
@@ -1817,6 +1877,15 @@ export declare interface LuaAgentConfig {
1817
1877
  persona: PersonaText;
1818
1878
  /** LLM model to use — 'provider/model' string or resolver function */
1819
1879
  model?: LuaAgentModel;
1880
+ /**
1881
+ * Per-call sampling settings (temperature, topP, maxOutputTokens, etc.).
1882
+ * Passed straight through to Mastra / AI SDK on every `chat/stream` and
1883
+ * `chat/generate`. Undefined leaves provider defaults in place.
1884
+ *
1885
+ * @example
1886
+ * modelSettings: { temperature: 0.2, maxOutputTokens: 4096 }
1887
+ */
1888
+ modelSettings?: AgentModelSettings;
1820
1889
  /** Array of skills (each with tools) */
1821
1890
  skills?: LuaSkill[];
1822
1891
  /** Array of webhooks */
@@ -2796,6 +2865,7 @@ declare const LuaVoiceConfigSchema: z.ZodEffects<z.ZodObject<{
2796
2865
  volume: z.ZodOptional<z.ZodNumber>;
2797
2866
  pronunciations: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
2798
2867
  persistTranscript: z.ZodOptional<z.ZodBoolean>;
2868
+ onToolFailureSay: z.ZodOptional<z.ZodString>;
2799
2869
  }, "strip", z.ZodTypeAny, {
2800
2870
  vad?: string;
2801
2871
  stt?: {
@@ -2888,6 +2958,7 @@ declare const LuaVoiceConfigSchema: z.ZodEffects<z.ZodObject<{
2888
2958
  };
2889
2959
  pronunciations?: Record<string, string>;
2890
2960
  persistTranscript?: boolean;
2961
+ onToolFailureSay?: string;
2891
2962
  }, {
2892
2963
  vad?: string;
2893
2964
  stt?: {
@@ -2980,6 +3051,7 @@ declare const LuaVoiceConfigSchema: z.ZodEffects<z.ZodObject<{
2980
3051
  };
2981
3052
  pronunciations?: Record<string, string>;
2982
3053
  persistTranscript?: boolean;
3054
+ onToolFailureSay?: string;
2983
3055
  }>, {
2984
3056
  vad?: string;
2985
3057
  stt?: {
@@ -3072,6 +3144,7 @@ declare const LuaVoiceConfigSchema: z.ZodEffects<z.ZodObject<{
3072
3144
  };
3073
3145
  pronunciations?: Record<string, string>;
3074
3146
  persistTranscript?: boolean;
3147
+ onToolFailureSay?: string;
3075
3148
  }, {
3076
3149
  vad?: string;
3077
3150
  stt?: {
@@ -3164,6 +3237,7 @@ declare const LuaVoiceConfigSchema: z.ZodEffects<z.ZodObject<{
3164
3237
  };
3165
3238
  pronunciations?: Record<string, string>;
3166
3239
  persistTranscript?: boolean;
3240
+ onToolFailureSay?: string;
3167
3241
  }>;
3168
3242
 
3169
3243
  /**
@@ -3279,6 +3353,21 @@ export declare interface LuaVoiceToolCtx {
3279
3353
  mode?: 'bridge' | 'refer';
3280
3354
  announce?: string;
3281
3355
  }): Promise<void>;
3356
+ /**
3357
+ * End the live call. When `announce` is set, the agent speaks it and
3358
+ * waits for playout before closing the session — useful for a sign-off
3359
+ * like "Thanks for calling, goodbye." Without `announce`, the session
3360
+ * closes immediately (any in-flight TTS finishes via the SDK's
3361
+ * graceful `close()`).
3362
+ *
3363
+ * @example
3364
+ * ```typescript
3365
+ * await ctx.voice?.endCall({ announce: 'Thanks for calling. Goodbye.' });
3366
+ * ```
3367
+ */
3368
+ endCall?(opts?: {
3369
+ announce?: string;
3370
+ }): Promise<void>;
3282
3371
  /**
3283
3372
  * @experimental Reserved for Phase 5 (BAC-213). Optional because
3284
3373
  * unimplemented — the actual "lock the assistant's current
@@ -27,13 +27,14 @@ var init_baskets = __esm({
27
27
  // src/config/constants.ts
28
28
  import { join } from "path";
29
29
  import { homedir } from "os";
30
- var CLI_CONFIG_DIR, VERSION_CHECK_FILE, TELEMETRY_FILE, BASE_URLS, CREDENTIALS_FILE, SANDBOX_STORAGE_FILE;
30
+ var CLI_CONFIG_DIR, VERSION_CHECK_FILE, TELEMETRY_FILE, CLI_CACHE_FILE, BASE_URLS, CREDENTIALS_FILE, SANDBOX_STORAGE_FILE, AUTH_STORAGE_FILE;
31
31
  var init_constants = __esm({
32
32
  "src/config/constants.ts"() {
33
33
  "use strict";
34
34
  CLI_CONFIG_DIR = join(homedir(), ".lua-cli");
35
35
  VERSION_CHECK_FILE = join(CLI_CONFIG_DIR, "version-check.json");
36
36
  TELEMETRY_FILE = join(CLI_CONFIG_DIR, "telemetry.json");
37
+ CLI_CACHE_FILE = join(CLI_CONFIG_DIR, "cache.json");
37
38
  BASE_URLS = {
38
39
  API: process.env.LUA_API_URL || "https://api.heylua.ai",
39
40
  AUTH: process.env.LUA_AUTH_URL || "https://auth.heylua.ai",
@@ -43,6 +44,7 @@ var init_constants = __esm({
43
44
  };
44
45
  CREDENTIALS_FILE = join(CLI_CONFIG_DIR, "credentials");
45
46
  SANDBOX_STORAGE_FILE = join(CLI_CONFIG_DIR, "sandbox.json");
47
+ AUTH_STORAGE_FILE = join(CLI_CONFIG_DIR, "auth.json");
46
48
  }
47
49
  });
48
50
 
@@ -787,7 +789,14 @@ Feel free to add, remove, or rename sections. Your persona can be a single parag
787
789
  // `Data.get('call:<sessionId>')` to drive post-call analytics, follow-ups,
788
790
  // or QA workflows. Defaults to false — most calls don't need to keep
789
791
  // a transcript copy.
790
- persistTranscript: z.boolean().optional()
792
+ persistTranscript: z.boolean().optional(),
793
+ // Spoken acknowledgement played when a tool call fails. When a tool
794
+ // throws, times out, or returns an unsupported result, the adapter calls
795
+ // `session.say(text)` once per failed call before surfacing the error
796
+ // to the LLM as a ToolError — fills the 2–3s gap before the LLM's own
797
+ // recovery response. Persona-specific (keep it short and on-brand);
798
+ // absent → no spoken fallback (the LLM's recovery is the only signal).
799
+ onToolFailureSay: z.string().min(1).max(200).optional()
791
800
  });
792
801
  LuaVoiceConfigSchema = LuaVoiceConfigInnerSchema.superRefine((cfg, ctx) => {
793
802
  const isRealtime = cfg.llm.kind === "realtime";
@@ -5661,6 +5670,38 @@ var LuaMCPServer = class {
5661
5670
  return base;
5662
5671
  }
5663
5672
  };
5673
+ function validateModelSettings(settings) {
5674
+ const finiteNumberKeys = [
5675
+ "temperature",
5676
+ "topP",
5677
+ "topK",
5678
+ "maxOutputTokens",
5679
+ "presencePenalty",
5680
+ "frequencyPenalty",
5681
+ "seed"
5682
+ ];
5683
+ for (const key of finiteNumberKeys) {
5684
+ const value = settings[key];
5685
+ if (value !== void 0 && (typeof value !== "number" || !Number.isFinite(value))) {
5686
+ throw new Error(`Agent modelSettings.${key} must be a finite number`);
5687
+ }
5688
+ }
5689
+ if (settings.temperature !== void 0 && (settings.temperature < 0 || settings.temperature > 2)) {
5690
+ throw new Error("Agent modelSettings.temperature must be between 0 and 2");
5691
+ }
5692
+ if (settings.topP !== void 0 && (settings.topP < 0 || settings.topP > 1)) {
5693
+ throw new Error("Agent modelSettings.topP must be between 0 and 1");
5694
+ }
5695
+ if (settings.maxOutputTokens !== void 0 && settings.maxOutputTokens < 1) {
5696
+ throw new Error("Agent modelSettings.maxOutputTokens must be >= 1");
5697
+ }
5698
+ if (settings.stopSequences !== void 0) {
5699
+ if (!Array.isArray(settings.stopSequences) || !settings.stopSequences.every((v) => typeof v === "string")) {
5700
+ throw new Error("Agent modelSettings.stopSequences must be a string array");
5701
+ }
5702
+ }
5703
+ }
5704
+ __name(validateModelSettings, "validateModelSettings");
5664
5705
  var LuaAgent = class {
5665
5706
  static {
5666
5707
  __name(this, "LuaAgent");
@@ -5668,6 +5709,7 @@ var LuaAgent = class {
5668
5709
  name;
5669
5710
  persona;
5670
5711
  model;
5712
+ modelSettings;
5671
5713
  skills;
5672
5714
  webhooks;
5673
5715
  jobs;
@@ -5699,6 +5741,10 @@ var LuaAgent = class {
5699
5741
  this.name = config.name;
5700
5742
  this.persona = config.persona;
5701
5743
  this.model = config.model;
5744
+ if (config.modelSettings !== void 0) {
5745
+ validateModelSettings(config.modelSettings);
5746
+ }
5747
+ this.modelSettings = config.modelSettings;
5702
5748
  if (typeof this.persona === "object") {
5703
5749
  if (!this.persona.base && !this.persona.voice && !this.persona.text) {
5704
5750
  throw new Error("Agent persona object must have at least one of: base, voice, text");
@@ -5725,6 +5771,9 @@ var LuaAgent = class {
5725
5771
  getModel() {
5726
5772
  return this.model;
5727
5773
  }
5774
+ getModelSettings() {
5775
+ return this.modelSettings;
5776
+ }
5728
5777
  getSkills() {
5729
5778
  return this.skills;
5730
5779
  }