lua-cli 3.21.0 → 3.23.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.
@@ -1,6 +1,7 @@
1
1
  import { CallWarning } from 'ai';
2
2
  import { FinishReason } from 'ai';
3
3
  import { LanguageModelUsage } from 'ai';
4
+ import { ModelMessage } from 'ai';
4
5
  import { ReasoningOutput } from 'ai';
5
6
  import { UserContent } from 'ai';
6
7
  import { z } from 'zod';
@@ -62,6 +63,11 @@ declare interface AgentInvocationInput {
62
63
  /** Per-call timeout in ms. Absent ⇒ the client default (120s). Set by scheduled agent jobs
63
64
  * to 180s so the cloud tier cuts off at the same point the desktop's local runner does. */
64
65
  timeoutMs?: number;
66
+ /** Per-request model override ("provider/model" code). Unknown codes fall back per
67
+ * approved-models policy server-side. */
68
+ model?: string;
69
+ /** Task 14 (tasks-redesign) — per-task connector + skill scoping. See `AgentToolScope`. */
70
+ toolScope?: AgentToolScope;
65
71
  }
66
72
 
67
73
  /**
@@ -175,6 +181,23 @@ export declare interface AgentsApi {
175
181
  invoke(targetAgentId: string, input: AgentInvocationInput): Promise<AgentInvocationOutput>;
176
182
  }
177
183
 
184
+ /**
185
+ * Task 14 (tasks-redesign) — per-task connector + skill scoping for a scheduled
186
+ * agent run. Non-empty `connectionIds` restricts the turn's MCP servers to the
187
+ * listed agent connections; non-empty `skillIds` restricts the turn's skills.
188
+ * Absent field or empty array ⇒ no filtering (the agent's full toolset).
189
+ *
190
+ * SECURITY: only honored on internally-authenticated invocations (the
191
+ * `X-Internal-Auth` agent-invoke path used by the server-side job runner) —
192
+ * lua-core drops it from any client-authenticated `/chat/*` request.
193
+ */
194
+ declare interface AgentToolScope {
195
+ /** Allowlisted agent connection ids (UnifiedTo `unifiedId`s). */
196
+ connectionIds?: string[];
197
+ /** Allowlisted skill ids (from the agent's `subAgent.skills`). */
198
+ skillIds?: string[];
199
+ }
200
+
178
201
  export declare const AI: AiApi;
179
202
 
180
203
  /**
@@ -219,13 +242,13 @@ export declare interface AiApi {
219
242
  /**
220
243
  * Wire-format input for sandbox `AI.generate` / `POST .../generate` (JSON-serializable).
221
244
  * Serializable subset of AI SDK `generateText` parameters.
222
- * `messages` is untyped over HTTP; callers typically send AI SDK `ModelMessage[]`.
223
245
  */
224
246
  export declare interface AiGenerateInput {
225
247
  model?: string;
226
248
  system?: string;
227
249
  prompt?: string;
228
- messages?: unknown[];
250
+ /** AI SDK `ModelMessage[]`. Server-validated; malformed messages are rejected with 400. */
251
+ messages?: ModelMessage[];
229
252
  temperature?: number;
230
253
  maxOutputTokens?: number;
231
254
  /**
@@ -1081,6 +1104,12 @@ declare interface CustomDataAPI {
1081
1104
  * @returns Promise resolving to update response
1082
1105
  */
1083
1106
  update(collectionName: string, entryId: string, data: Record<string, any>, searchText?: string): Promise<UpdateCustomDataResponse>;
1107
+ /** Atomically sets and removes top-level entry fields and optionally changes search text. */
1108
+ patch(collectionName: string, entryId: string, mutation: {
1109
+ set?: Record<string, any>;
1110
+ unset?: string[];
1111
+ searchText?: string | null;
1112
+ }): Promise<UpdateCustomDataResponse>;
1084
1113
  /**
1085
1114
  * Performs vector search on a collection.
1086
1115
  * @param collectionName - Collection name
@@ -1211,6 +1240,12 @@ export declare class DataEntryInstance {
1211
1240
  * @throws Error if the update fails
1212
1241
  */
1213
1242
  update(data: Record<string, any>, searchText?: string): Promise<Record<string, any>>;
1243
+ patch(mutation: {
1244
+ set?: Record<string, any>;
1245
+ unset?: string[];
1246
+ searchText?: string | null;
1247
+ }): Promise<Record<string, any>>;
1248
+ unset(...fields: string[]): Promise<Record<string, any>>;
1214
1249
  /**
1215
1250
  * Deletes the custom data entry
1216
1251
  * @returns Promise resolving to true if deletion was successful
@@ -2546,7 +2581,7 @@ export declare class LuaJob {
2546
2581
  * @param config.name - Job name (required; non-empty string)
2547
2582
  * @param config.description - Short description of what the job does (1-2 sentences)
2548
2583
  * @param config.schedule - Schedule configuration (cron, once, or interval)
2549
- * @param config.timeout - Optional timeout in seconds (default: 300)
2584
+ * @param config.timeout - Optional timeout in seconds (default: 300, supported range: 1-600)
2550
2585
  * @param config.retry - Optional retry configuration
2551
2586
  * @param config.metadata - Optional metadata for the job
2552
2587
  * @param config.execute - Function that processes the job (receives job instance as parameter)
@@ -2603,7 +2638,7 @@ export declare interface LuaJobConfig {
2603
2638
  * Receives metadata as parameter for accessing job configuration.
2604
2639
  */
2605
2640
  execute: (job: JobInstance) => Promise<any>;
2606
- /** Optional timeout in seconds (default: 300) */
2641
+ /** Optional timeout in seconds (default: 300, supported range: 1-600) */
2607
2642
  timeout?: number;
2608
2643
  /** Optional retry configuration */
2609
2644
  retry?: {
@@ -2717,12 +2752,30 @@ export declare interface LuaRuntime {
2717
2752
  * // Or add tools after construction
2718
2753
  * skill.addTool(anotherTool);
2719
2754
  * ```
2755
+ *
2756
+ * @example
2757
+ * ```typescript
2758
+ * // Skill with condition - the whole skill is hidden from non-premium users
2759
+ * class PremiumSkill extends LuaSkill {
2760
+ * name = "premium-skill";
2761
+ * description = "Advanced tools for premium users";
2762
+ * context = "Use these tools for premium workflows.";
2763
+ * tools = [premiumSearchTool];
2764
+ *
2765
+ * // Condition runs before the skill's tools and context reach the LLM
2766
+ * condition = async () => {
2767
+ * const user = await User.get();
2768
+ * return user.data?.isPremium === true;
2769
+ * };
2770
+ * }
2771
+ * ```
2720
2772
  */
2721
2773
  export declare class LuaSkill {
2722
2774
  private readonly tools;
2723
2775
  private readonly name;
2724
2776
  private readonly description;
2725
2777
  private readonly context;
2778
+ private readonly condition?;
2726
2779
  /**
2727
2780
  * Creates a new LuaSkill instance.
2728
2781
  *
@@ -2731,9 +2784,11 @@ export declare class LuaSkill {
2731
2784
  * @param config.description - Short description of what the skill does (1-2 sentences)
2732
2785
  * @param config.context - Detailed explanation of how the agent should use the tools
2733
2786
  * @param config.tools - Optional array of tools to add immediately
2787
+ * @param config.condition - Optional async gate; false hides the skill's tools and context
2734
2788
  */
2735
2789
  constructor(config: LuaSkillConfig);
2736
2790
  getContext(): SkillContextText;
2791
+ getCondition(): (() => Promise<boolean>) | undefined;
2737
2792
  /**
2738
2793
  * Adds a single tool to the skill.
2739
2794
  * Tool name is validated before being added.
@@ -2775,6 +2830,12 @@ declare interface LuaSkillConfig {
2775
2830
  context: SkillContextText;
2776
2831
  /** Optional array of tools to add during construction */
2777
2832
  tools?: LuaTool<any>[];
2833
+ /**
2834
+ * Optional async function that determines if the whole skill should be
2835
+ * available. When it returns false the skill's tools are hidden AND the
2836
+ * skill's context is left out of the agent prompt.
2837
+ */
2838
+ condition?: () => Promise<boolean>;
2778
2839
  }
2779
2840
 
2780
2841
  export declare interface LuaTool<TInput extends ZodType = ZodType> {
@@ -5038,6 +5099,9 @@ export declare interface SendTemplateValues {
5038
5099
  image_url?: string;
5039
5100
  video_url?: string;
5040
5101
  document_url?: string;
5102
+ image_id?: string;
5103
+ video_id?: string;
5104
+ document_id?: string;
5041
5105
  document_filename?: string;
5042
5106
  };
5043
5107
  body?: Record<string, string>;
@@ -5373,6 +5437,11 @@ declare interface UserDataAPI {
5373
5437
  * @returns Promise resolving to updated user data
5374
5438
  */
5375
5439
  update(data: Record<string, any>): Promise<any>;
5440
+ /** Atomically sets and removes top-level user data fields. */
5441
+ patch(mutation: {
5442
+ set?: Record<string, any>;
5443
+ unset?: string[];
5444
+ }): Promise<any>;
5376
5445
  /**
5377
5446
  * Clears user data.
5378
5447
  * @returns Promise resolving when data is cleared
@@ -5423,6 +5492,11 @@ export declare class UserDataInstance {
5423
5492
  * @throws Error if the update fails
5424
5493
  */
5425
5494
  update(data: Record<string, any>): Promise<any>;
5495
+ patch(mutation: {
5496
+ set?: Record<string, any>;
5497
+ unset?: string[];
5498
+ }): Promise<any>;
5499
+ unset(...fields: string[]): Promise<any>;
5426
5500
  /**
5427
5501
  * Clears all user data for the current user
5428
5502
  * @returns Promise resolving to true if clearing was successful
@@ -84,6 +84,27 @@ function isAllowedReviewableExecuteTool(tool) {
84
84
  function isReviewableMcpSendTool(tool) {
85
85
  return tool.length > REVIEWABLE_MCP_SEND_TOOL_SUFFIX.length && tool.endsWith(REVIEWABLE_MCP_SEND_TOOL_SUFFIX);
86
86
  }
87
+ function mcpActionTokens(action) {
88
+ return action.replace(/([a-z0-9])([A-Z])/g, "$1 $2").toLowerCase().split(/[^a-z0-9]+/).filter(Boolean);
89
+ }
90
+ function isReviewableMcpDraftTool(tool) {
91
+ const sep = tool.indexOf("_");
92
+ if (sep <= 0 || sep >= tool.length - 1) return false;
93
+ const action = tool.slice(sep + 1);
94
+ const tokens = mcpActionTokens(action);
95
+ if (!tokens.includes("draft") && !tokens.includes("drafts")) return false;
96
+ return !MCP_TOOL_READ_VERB_RE.test(action);
97
+ }
98
+ function isMcpDraftCreateTool(tool) {
99
+ if (!isReviewableMcpDraftTool(tool)) return false;
100
+ const tokens = mcpActionTokens(tool.slice(tool.indexOf("_") + 1));
101
+ return tokens[0] === "draft" || tokens.some((t) => MCP_DRAFT_CREATE_VERBS.has(t));
102
+ }
103
+ function mcpSendSiblingForDraftTool(tool, availableToolIds) {
104
+ const sibling = `${tool.split("_")[0]}${REVIEWABLE_MCP_SEND_TOOL_SUFFIX}`;
105
+ for (const id of availableToolIds) if (id === sibling) return sibling;
106
+ return void 0;
107
+ }
87
108
  function isReviewableExecuteTool(tool) {
88
109
  return isAllowedReviewableExecuteTool(tool) || isReviewableMcpSendTool(tool);
89
110
  }
@@ -323,7 +344,23 @@ function foldRichPartsIntoMessages(messages, records, makeMessage, sameTurnGroup
323
344
  function buildDefaultPersona(agentName) {
324
345
  return DEFAULT_PERSONA_GUIDE.replace(AGENT_NAME_TOKEN, () => agentName || "My Agent");
325
346
  }
326
- var __defProp2, __name2, CHANNEL_SEND_CHANNELS, REVIEWABLE_ACTION_EXECUTE_TOOL_ALLOWLIST, REVIEWABLE_MCP_SEND_TOOL_SUFFIX, NON_INTERACTIVE_CHANNELS, RICH_PARTS_MESSAGE_ID_PREFIX, SCREENSHOT_MESSAGE_ID_PREFIX, BROWSER_COMMANDS, BROWSER_COMMAND_NAMES, REASONING_EFFORT_VALUES, AGENT_NAME_TOKEN, DEFAULT_PERSONA_GUIDE, VoiceNameSchema, PluginProviderSchema, RealtimeProviderSchema, PluginClassSchema, ModelDescriptorSchema, InferenceModelSchema, PluginModelSchema, RealtimeModelSchema, LuaVoiceModelSchema, TurnDetectionSchema, InterruptionSchema, BuiltinAudioClipSchema, AudioConfigSchema, BackgroundAudioEntrySchema, BackgroundAudioSchema, LuaVoiceConfigInnerSchema, LuaVoiceConfigSchema, LuaVoiceRefSchema;
347
+ function resolveLuaJobTimeoutSeconds(timeout) {
348
+ const resolved = timeout ?? LUA_JOB_DEFAULT_TIMEOUT_SECONDS;
349
+ if (!Number.isInteger(resolved)) {
350
+ throw new TypeError("LuaJob `timeout` must be an integer number of seconds.");
351
+ }
352
+ if (resolved < LUA_JOB_MIN_TIMEOUT_SECONDS || resolved > LUA_JOB_MAX_TIMEOUT_SECONDS) {
353
+ throw new RangeError(`LuaJob \`timeout\` must be between ${LUA_JOB_MIN_TIMEOUT_SECONDS} and ${LUA_JOB_MAX_TIMEOUT_SECONDS} seconds.`);
354
+ }
355
+ return resolved;
356
+ }
357
+ function normalizeLuaJobExecutionTimeoutSeconds(timeout) {
358
+ if (typeof timeout !== "number" || !Number.isFinite(timeout)) {
359
+ return LUA_JOB_DEFAULT_TIMEOUT_SECONDS;
360
+ }
361
+ return Math.min(Math.max(timeout, LUA_JOB_MIN_TIMEOUT_SECONDS), LUA_JOB_MAX_TIMEOUT_SECONDS);
362
+ }
363
+ var __defProp2, __name2, CHANNEL_SEND_CHANNELS, REVIEWABLE_ACTION_EXECUTE_TOOL_ALLOWLIST, REVIEWABLE_MCP_SEND_TOOL_SUFFIX, MCP_TOOL_READ_VERB_RE, MCP_DRAFT_CREATE_VERBS, NON_INTERACTIVE_CHANNELS, RICH_PARTS_MESSAGE_ID_PREFIX, SCREENSHOT_MESSAGE_ID_PREFIX, BROWSER_COMMANDS, BROWSER_COMMAND_NAMES, REASONING_EFFORT_VALUES, AGENT_NAME_TOKEN, DEFAULT_PERSONA_GUIDE, VoiceNameSchema, PluginProviderSchema, RealtimeProviderSchema, PluginClassSchema, ModelDescriptorSchema, InferenceModelSchema, PluginModelSchema, RealtimeModelSchema, LuaVoiceModelSchema, TurnDetectionSchema, InterruptionSchema, BuiltinAudioClipSchema, AudioConfigSchema, BackgroundAudioEntrySchema, BackgroundAudioSchema, LuaVoiceConfigInnerSchema, LuaVoiceConfigSchema, LuaVoiceRefSchema, LUA_JOB_DEFAULT_TIMEOUT_SECONDS, LUA_JOB_MIN_TIMEOUT_SECONDS, LUA_JOB_MAX_TIMEOUT_SECONDS;
327
364
  var init_dist = __esm({
328
365
  "../shared-types/dist/index.mjs"() {
329
366
  "use strict";
@@ -366,6 +403,26 @@ var init_dist = __esm({
366
403
  REVIEWABLE_MCP_SEND_TOOL_SUFFIX = "_create_messaging_message";
367
404
  __name(isReviewableMcpSendTool, "isReviewableMcpSendTool");
368
405
  __name2(isReviewableMcpSendTool, "isReviewableMcpSendTool");
406
+ MCP_TOOL_READ_VERB_RE = /^(list|get|search|read|fetch|find|query|describe|count|retrieve|lookup|show|view)(_|[A-Z0-9]|$)/;
407
+ __name(mcpActionTokens, "mcpActionTokens");
408
+ __name2(mcpActionTokens, "mcpActionTokens");
409
+ __name(isReviewableMcpDraftTool, "isReviewableMcpDraftTool");
410
+ __name2(isReviewableMcpDraftTool, "isReviewableMcpDraftTool");
411
+ MCP_DRAFT_CREATE_VERBS = /* @__PURE__ */ new Set([
412
+ "create",
413
+ "compose",
414
+ "make",
415
+ "new",
416
+ "save",
417
+ "add",
418
+ "write",
419
+ "stage",
420
+ "prepare"
421
+ ]);
422
+ __name(isMcpDraftCreateTool, "isMcpDraftCreateTool");
423
+ __name2(isMcpDraftCreateTool, "isMcpDraftCreateTool");
424
+ __name(mcpSendSiblingForDraftTool, "mcpSendSiblingForDraftTool");
425
+ __name2(mcpSendSiblingForDraftTool, "mcpSendSiblingForDraftTool");
369
426
  __name(isReviewableExecuteTool, "isReviewableExecuteTool");
370
427
  __name2(isReviewableExecuteTool, "isReviewableExecuteTool");
371
428
  NON_INTERACTIVE_CHANNELS = [
@@ -398,11 +455,11 @@ var init_dist = __esm({
398
455
  },
399
456
  {
400
457
  name: "session_open",
401
- description: "Open/attach a browser session (its own cookies/auth). Args: url?, headed?, profile?, confirmActions?."
458
+ description: "Open/attach a browser session (its own cookies/auth). Args: url?, headed?, profile?, confirmActions?. Only use the browser when the user explicitly asked for it, or said yes when you asked. For reading a page's content use fetchUrl first."
402
459
  },
403
460
  {
404
461
  name: "navigate",
405
- description: "Navigate the session to a URL. Args: url, waitUntil?."
462
+ description: "Navigate the session to a URL. Args: url, waitUntil?. Only use the browser when the user explicitly asked for it, or said yes when you asked. For reading a page's content use fetchUrl first."
406
463
  },
407
464
  {
408
465
  name: "back",
@@ -898,6 +955,13 @@ Feel free to add, remove, or rename sections. Your persona can be a single parag
898
955
  voiceId: z.string().min(1),
899
956
  version: z.string().optional()
900
957
  });
958
+ LUA_JOB_DEFAULT_TIMEOUT_SECONDS = 300;
959
+ LUA_JOB_MIN_TIMEOUT_SECONDS = 1;
960
+ LUA_JOB_MAX_TIMEOUT_SECONDS = 600;
961
+ __name(resolveLuaJobTimeoutSeconds, "resolveLuaJobTimeoutSeconds");
962
+ __name2(resolveLuaJobTimeoutSeconds, "resolveLuaJobTimeoutSeconds");
963
+ __name(normalizeLuaJobExecutionTimeoutSeconds, "normalizeLuaJobExecutionTimeoutSeconds");
964
+ __name2(normalizeLuaJobExecutionTimeoutSeconds, "normalizeLuaJobExecutionTimeoutSeconds");
901
965
  }
902
966
  });
903
967
 
@@ -2233,6 +2297,18 @@ var init_skill_handler = __esm({
2233
2297
  return toolData;
2234
2298
  }).filter(Boolean);
2235
2299
  const sourceArchive = buildSourceArchive(archiveEntries);
2300
+ let condition;
2301
+ let conditionS3Hash;
2302
+ if (skill.hasCondition) {
2303
+ const skillCode = loadArtifact(skill, projectPath);
2304
+ if (bundleAccumulator) {
2305
+ const rawGzip = compressForPushRaw(skillCode);
2306
+ conditionS3Hash = hashBundle(rawGzip);
2307
+ bundleAccumulator.set(conditionS3Hash, rawGzip);
2308
+ } else {
2309
+ condition = compressForPush(skillCode);
2310
+ }
2311
+ }
2236
2312
  return {
2237
2313
  name: skill.name,
2238
2314
  description: skill.description,
@@ -2241,6 +2317,12 @@ var init_skill_handler = __esm({
2241
2317
  context: skill.context
2242
2318
  } : {},
2243
2319
  tools,
2320
+ ...condition ? {
2321
+ condition
2322
+ } : {},
2323
+ ...conditionS3Hash ? {
2324
+ conditionS3Hash
2325
+ } : {},
2244
2326
  ...sourceArchive ? {
2245
2327
  sourceArchive,
2246
2328
  archiveSchemaVersion: SOURCE_ARCHIVE_SCHEMA_VERSION
@@ -3780,6 +3862,8 @@ var init_user_instance = __esm({
3780
3862
  "data",
3781
3863
  "userAPI",
3782
3864
  "update",
3865
+ "patch",
3866
+ "unset",
3783
3867
  "clear",
3784
3868
  "toJSON",
3785
3869
  "_luaProfile"
@@ -3858,9 +3942,27 @@ var init_user_instance = __esm({
3858
3942
  this.data = response;
3859
3943
  return this.data;
3860
3944
  } catch (error) {
3861
- throw new Error("Failed to update user data");
3945
+ throw new Error("Failed to update user data", {
3946
+ cause: error
3947
+ });
3948
+ }
3949
+ }
3950
+ async patch(mutation) {
3951
+ try {
3952
+ const response = await this.userAPI.patch(mutation);
3953
+ this.data = response;
3954
+ return this.data;
3955
+ } catch (error) {
3956
+ throw new Error("Failed to patch user data", {
3957
+ cause: error
3958
+ });
3862
3959
  }
3863
3960
  }
3961
+ async unset(...fields) {
3962
+ return this.patch({
3963
+ unset: fields
3964
+ });
3965
+ }
3864
3966
  /**
3865
3967
  * Clears all user data for the current user
3866
3968
  * @returns Promise resolving to true if clearing was successful
@@ -3869,9 +3971,12 @@ var init_user_instance = __esm({
3869
3971
  async clear() {
3870
3972
  try {
3871
3973
  await this.userAPI.clear();
3974
+ this.data = {};
3872
3975
  return true;
3873
3976
  } catch (error) {
3874
- throw new Error("Failed to clear user data");
3977
+ throw new Error("Failed to clear user data", {
3978
+ cause: error
3979
+ });
3875
3980
  }
3876
3981
  }
3877
3982
  /**
@@ -3884,7 +3989,9 @@ var init_user_instance = __esm({
3884
3989
  await this.userAPI.update(this.data);
3885
3990
  return true;
3886
3991
  } catch (error) {
3887
- throw new Error("Failed to save user data");
3992
+ throw new Error("Failed to save user data", {
3993
+ cause: error
3994
+ });
3888
3995
  }
3889
3996
  }
3890
3997
  /**
@@ -3898,7 +4005,9 @@ var init_user_instance = __esm({
3898
4005
  await this.userAPI.sendMessage(messages);
3899
4006
  return true;
3900
4007
  } catch (error) {
3901
- throw new Error("Failed to send message");
4008
+ throw new Error("Failed to send message", {
4009
+ cause: error
4010
+ });
3902
4011
  }
3903
4012
  }
3904
4013
  //get chat history
@@ -3906,7 +4015,9 @@ var init_user_instance = __esm({
3906
4015
  try {
3907
4016
  return await this.userAPI.getChatHistory();
3908
4017
  } catch (error) {
3909
- throw new Error("Failed to get chat history");
4018
+ throw new Error("Failed to get chat history", {
4019
+ cause: error
4020
+ });
3910
4021
  }
3911
4022
  }
3912
4023
  };
@@ -3921,22 +4032,28 @@ var init_user_data_api_service = __esm({
3921
4032
  init_http_client();
3922
4033
  init_user_instance();
3923
4034
  init_lazy_instances();
3924
- UserDataApi = class extends HttpClient {
4035
+ UserDataApi = class _UserDataApi extends HttpClient {
3925
4036
  static {
3926
4037
  __name(this, "UserDataApi");
3927
4038
  }
3928
4039
  apiKey;
3929
4040
  agentId;
4041
+ targetUserId;
3930
4042
  /**
3931
4043
  * Creates an instance of UserDataApi
3932
4044
  * @param baseUrl - The base URL for the API
3933
4045
  * @param apiKey - The API key for authentication
3934
4046
  * @param agentId - The unique identifier of the agent
3935
4047
  */
3936
- constructor(baseUrl, apiKey, agentId) {
4048
+ constructor(baseUrl, apiKey, agentId, targetUserId) {
3937
4049
  super(baseUrl);
3938
4050
  this.apiKey = apiKey;
3939
4051
  this.agentId = agentId;
4052
+ this.targetUserId = targetUserId;
4053
+ }
4054
+ get dataPath() {
4055
+ const base = `/developer/user/data/agent/${this.agentId}`;
4056
+ return this.targetUserId ? `${base}/user/${encodeURIComponent(this.targetUserId)}` : base;
3940
4057
  }
3941
4058
  /**
3942
4059
  * Retrieves user data by userId, email, or phone.
@@ -3955,7 +4072,7 @@ var init_user_data_api_service = __esm({
3955
4072
  }
3956
4073
  let url = `/developer/user/data/agent/${this.agentId}`;
3957
4074
  if (userId) {
3958
- url += `/user/${userId}`;
4075
+ url += `/user/${encodeURIComponent(userId)}`;
3959
4076
  }
3960
4077
  const response = await this.httpGet(url, {
3961
4078
  Authorization: `Bearer ${this.apiKey}`
@@ -3965,7 +4082,8 @@ var init_user_data_api_service = __esm({
3965
4082
  }
3966
4083
  const profile = response.data?._luaProfile;
3967
4084
  const { _luaProfile, ...data } = response.data || {};
3968
- return new UserDataInstance(this, data, profile);
4085
+ const scopedApi = userId ? new _UserDataApi(this.baseUrl, this.apiKey, this.agentId, userId) : this;
4086
+ return new UserDataInstance(scopedApi, data, profile);
3969
4087
  }
3970
4088
  /**
3971
4089
  * Resolves email or phone to user profile via DeveloperApi
@@ -3976,11 +4094,11 @@ var init_user_data_api_service = __esm({
3976
4094
  try {
3977
4095
  const developerApi = await getDeveloperInstance();
3978
4096
  if (options.email) {
3979
- const response = await developerApi.getUserProfileByEmail(options.email);
4097
+ const response = await developerApi.getUserProfileByEmail(options.email, this.agentId);
3980
4098
  return response.success ? response.data ?? null : null;
3981
4099
  }
3982
4100
  if (options.phone) {
3983
- const response = await developerApi.getUserProfileByPhone(options.phone);
4101
+ const response = await developerApi.getUserProfileByPhone(options.phone, this.agentId);
3984
4102
  return response.success ? response.data ?? null : null;
3985
4103
  }
3986
4104
  } catch (error) {
@@ -3998,7 +4116,7 @@ var init_user_data_api_service = __esm({
3998
4116
  * @throws Error if the update fails or the request is unsuccessful
3999
4117
  */
4000
4118
  async update(data) {
4001
- const response = await this.httpPut(`/developer/user/data/agent/${this.agentId}`, data, {
4119
+ const response = await this.httpPut(this.dataPath, data, {
4002
4120
  Authorization: `Bearer ${this.apiKey}`
4003
4121
  });
4004
4122
  if (!response.success) {
@@ -4007,13 +4125,23 @@ var init_user_data_api_service = __esm({
4007
4125
  const { _luaProfile, ...cleanData } = response.data || {};
4008
4126
  return cleanData;
4009
4127
  }
4128
+ async patch(mutation) {
4129
+ const response = await this.httpPatch(this.dataPath, mutation, {
4130
+ Authorization: `Bearer ${this.apiKey}`
4131
+ });
4132
+ if (!response.success) {
4133
+ throw new Error(response.error?.message || "Failed to patch user data");
4134
+ }
4135
+ const { _luaProfile, ...cleanData } = response.data || {};
4136
+ return cleanData;
4137
+ }
4010
4138
  /**
4011
4139
  * Clears all user data for the current user and specific agent
4012
4140
  * @returns Promise resolving to an empty object upon successful deletion
4013
4141
  * @throws Error if the clear operation fails or the request is unsuccessful
4014
4142
  */
4015
4143
  async clear() {
4016
- const response = await this.httpDelete(`/developer/user/data/agent/${this.agentId}`, {
4144
+ const response = await this.httpDelete(this.dataPath, {
4017
4145
  Authorization: `Bearer ${this.apiKey}`
4018
4146
  });
4019
4147
  if (!response.success) {
@@ -4127,6 +4255,8 @@ var init_data_entry_instance = __esm({
4127
4255
  "score",
4128
4256
  "customDataAPI",
4129
4257
  "update",
4258
+ "patch",
4259
+ "unset",
4130
4260
  "delete",
4131
4261
  "toJSON"
4132
4262
  ];
@@ -4218,9 +4348,33 @@ var init_data_entry_instance = __esm({
4218
4348
  };
4219
4349
  return this.data;
4220
4350
  } catch (error) {
4221
- throw new Error("Failed to update custom data entry");
4351
+ throw new Error("Failed to update custom data entry", {
4352
+ cause: error
4353
+ });
4222
4354
  }
4223
4355
  }
4356
+ async patch(mutation) {
4357
+ try {
4358
+ await this.customDataAPI.patch(this.collectionName, this.id, mutation);
4359
+ this.data = {
4360
+ ...this.data,
4361
+ ...mutation.set ?? {}
4362
+ };
4363
+ for (const field of mutation.unset ?? []) {
4364
+ delete this.data[field];
4365
+ }
4366
+ return this.data;
4367
+ } catch (error) {
4368
+ throw new Error("Failed to patch custom data entry", {
4369
+ cause: error
4370
+ });
4371
+ }
4372
+ }
4373
+ async unset(...fields) {
4374
+ return this.patch({
4375
+ unset: fields
4376
+ });
4377
+ }
4224
4378
  /**
4225
4379
  * Deletes the custom data entry
4226
4380
  * @returns Promise resolving to true if deletion was successful
@@ -4231,7 +4385,9 @@ var init_data_entry_instance = __esm({
4231
4385
  await this.customDataAPI.delete(this.collectionName, this.id);
4232
4386
  return true;
4233
4387
  } catch (error) {
4234
- throw new Error("Failed to delete custom data entry");
4388
+ throw new Error("Failed to delete custom data entry", {
4389
+ cause: error
4390
+ });
4235
4391
  }
4236
4392
  }
4237
4393
  /**
@@ -4245,7 +4401,9 @@ var init_data_entry_instance = __esm({
4245
4401
  await this.customDataAPI.update(this.collectionName, this.id, this.data, searchText);
4246
4402
  return true;
4247
4403
  } catch (error) {
4248
- throw new Error("Failed to save data entry");
4404
+ throw new Error("Failed to save data entry", {
4405
+ cause: error
4406
+ });
4249
4407
  }
4250
4408
  }
4251
4409
  };
@@ -4356,6 +4514,15 @@ var init_custom_data_api_service = __esm({
4356
4514
  }
4357
4515
  throw new Error(response.error?.message || "Failed to update custom data entry");
4358
4516
  }
4517
+ async patch(collectionName, entryId, mutation) {
4518
+ const response = await this.httpPatch(`/developer/agents/${this.agentId}/custom-data/${collectionName}/${entryId}`, mutation, {
4519
+ Authorization: `Bearer ${this.apiKey}`
4520
+ });
4521
+ if (response.success && response.data) {
4522
+ return response.data;
4523
+ }
4524
+ throw new Error(response.error?.message || "Failed to patch custom data entry");
4525
+ }
4359
4526
  /**
4360
4527
  * Performs semantic search on custom data entries using text similarity
4361
4528
  * @param collectionName - The name of the collection to search within
@@ -5370,8 +5537,10 @@ var init_developer_api_service = __esm({
5370
5537
  * @param email - The email address to look up
5371
5538
  * @returns Promise resolving to an ApiResponse containing the profile, or null if not found
5372
5539
  */
5373
- async getUserProfileByEmail(email) {
5374
- return this.httpGet(`/developer/user/profile/email/${encodeURIComponent(email)}`, {
5540
+ async getUserProfileByEmail(email, agentId) {
5541
+ const path3 = `/developer/user/profile/email/${encodeURIComponent(email)}`;
5542
+ const scopedPath = agentId ? `${path3}?agentId=${encodeURIComponent(agentId)}` : path3;
5543
+ return this.httpGet(scopedPath, {
5375
5544
  Authorization: `Bearer ${this.apiKey}`
5376
5545
  });
5377
5546
  }
@@ -5380,9 +5549,11 @@ var init_developer_api_service = __esm({
5380
5549
  * @param phone - The phone number to look up (with or without + prefix)
5381
5550
  * @returns Promise resolving to an ApiResponse containing the profile, or null if not found
5382
5551
  */
5383
- async getUserProfileByPhone(phone) {
5552
+ async getUserProfileByPhone(phone, agentId) {
5384
5553
  const normalizedPhone = phone.replace(/^\+/, "");
5385
- return this.httpGet(`/developer/user/profile/phone/${normalizedPhone}`, {
5554
+ const path3 = `/developer/user/profile/phone/${normalizedPhone}`;
5555
+ const scopedPath = agentId ? `${path3}?agentId=${encodeURIComponent(agentId)}` : path3;
5556
+ return this.httpGet(scopedPath, {
5386
5557
  Authorization: `Bearer ${this.apiKey}`
5387
5558
  });
5388
5559
  }
@@ -5925,6 +6096,7 @@ __name(assertValidToolName, "assertValidToolName");
5925
6096
 
5926
6097
  // src/types/skill.ts
5927
6098
  init_dist();
6099
+ init_dist();
5928
6100
  var env = /* @__PURE__ */ __name((key) => {
5929
6101
  if (process.env[key]) {
5930
6102
  return process.env[key];
@@ -5945,6 +6117,7 @@ var LuaSkill = class {
5945
6117
  name;
5946
6118
  description;
5947
6119
  context;
6120
+ condition;
5948
6121
  /**
5949
6122
  * Creates a new LuaSkill instance.
5950
6123
  *
@@ -5953,6 +6126,7 @@ var LuaSkill = class {
5953
6126
  * @param config.description - Short description of what the skill does (1-2 sentences)
5954
6127
  * @param config.context - Detailed explanation of how the agent should use the tools
5955
6128
  * @param config.tools - Optional array of tools to add immediately
6129
+ * @param config.condition - Optional async gate; false hides the skill's tools and context
5956
6130
  */
5957
6131
  constructor(config) {
5958
6132
  if (!config.name || !config.name.trim()) {
@@ -5961,6 +6135,7 @@ var LuaSkill = class {
5961
6135
  this.name = config.name;
5962
6136
  this.description = config.description;
5963
6137
  this.context = config.context;
6138
+ this.condition = config.condition;
5964
6139
  if (typeof this.context === "object") {
5965
6140
  if (!this.context.base && !this.context.voice && !this.context.text) {
5966
6141
  throw new Error("Skill context object must have at least one of: base, voice, text");
@@ -5973,6 +6148,9 @@ var LuaSkill = class {
5973
6148
  getContext() {
5974
6149
  return this.context;
5975
6150
  }
6151
+ getCondition() {
6152
+ return this.condition;
6153
+ }
5976
6154
  /**
5977
6155
  * Adds a single tool to the skill.
5978
6156
  * Tool name is validated before being added.
@@ -6033,7 +6211,7 @@ var LuaJob = class {
6033
6211
  * @param config.name - Job name (required; non-empty string)
6034
6212
  * @param config.description - Short description of what the job does (1-2 sentences)
6035
6213
  * @param config.schedule - Schedule configuration (cron, once, or interval)
6036
- * @param config.timeout - Optional timeout in seconds (default: 300)
6214
+ * @param config.timeout - Optional timeout in seconds (default: 300, supported range: 1-600)
6037
6215
  * @param config.retry - Optional retry configuration
6038
6216
  * @param config.metadata - Optional metadata for the job
6039
6217
  * @param config.execute - Function that processes the job (receives job instance as parameter)
@@ -6045,7 +6223,7 @@ var LuaJob = class {
6045
6223
  this.name = config.name;
6046
6224
  this.description = config.description;
6047
6225
  this.schedule = config.schedule;
6048
- this.timeout = config.timeout || 300;
6226
+ this.timeout = resolveLuaJobTimeoutSeconds(config.timeout);
6049
6227
  this.retry = config.retry;
6050
6228
  this.metadata = config.metadata;
6051
6229
  this.executeFunction = config.execute;