lua-cli 3.29.0 → 3.29.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.
@@ -1840,6 +1840,7 @@ declare abstract class HttpClient {
1840
1840
  * cannot be recovered after an ambiguous network or server failure.
1841
1841
  */
1842
1842
  protected httpPostOnce<T>(url: string, data?: any, headers?: Record<string, string>): Promise<ApiResponse<T>>;
1843
+ protected httpPostCoreDrainRetry<T>(url: string, data?: any, headers?: Record<string, string>): Promise<ApiResponse<T>>;
1843
1844
  /**
1844
1845
  * Performs an HTTP PUT request
1845
1846
  * @param url - The relative URL path to request (will be appended to baseUrl)
@@ -370,6 +370,64 @@ function buildDefaultPersona(agentName) {
370
370
  function buildPersonalSpaceStartingPersona(agentName) {
371
371
  return PERSONAL_SPACE_STARTING_PERSONA.replace(new RegExp(AGENT_NAME_TOKEN.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"), "g"), () => agentName || "Your assistant");
372
372
  }
373
+ function isRecord(value) {
374
+ return typeof value === "object" && value !== null;
375
+ }
376
+ function isCoreDrainingErrorResponse(value) {
377
+ if (!isRecord(value) || !isRecord(value.error)) return false;
378
+ return value.error.code === CORE_DRAINING_CODE && typeof value.error.message === "string" && value.error.retryable === true;
379
+ }
380
+ function coreDrainingRetryDelayMs(retryAfter, nowMs = Date.now()) {
381
+ if (retryAfter === null) return CORE_DRAINING_DEFAULT_RETRY_MS;
382
+ const seconds = /^\d+$/.test(retryAfter.trim()) ? Number(retryAfter) : Number.NaN;
383
+ const delayMs = Number.isFinite(seconds) ? seconds * 1e3 : Date.parse(retryAfter) - nowMs;
384
+ if (!Number.isFinite(delayMs)) return CORE_DRAINING_DEFAULT_RETRY_MS;
385
+ return Math.min(Math.max(0, delayMs), CORE_DRAINING_MAX_RETRY_MS);
386
+ }
387
+ async function readCoreDrainingRetryDelayMs(response) {
388
+ if (response.status !== 503) return null;
389
+ try {
390
+ const payload = await response.clone().json();
391
+ if (!isCoreDrainingErrorResponse(payload)) return null;
392
+ } catch {
393
+ return null;
394
+ }
395
+ return coreDrainingRetryDelayMs(response.headers.get("Retry-After"));
396
+ }
397
+ function waitForCoreDrain(delayMs, signal) {
398
+ return new Promise((resolve, reject) => {
399
+ if (signal?.aborted) {
400
+ reject(signal.reason ?? new DOMException("Aborted", "AbortError"));
401
+ return;
402
+ }
403
+ const timer = setTimeout(() => {
404
+ signal?.removeEventListener("abort", onAbort);
405
+ resolve();
406
+ }, delayMs);
407
+ function onAbort() {
408
+ clearTimeout(timer);
409
+ reject(signal?.reason ?? new DOMException("Aborted", "AbortError"));
410
+ }
411
+ __name(onAbort, "onAbort");
412
+ __name2(onAbort, "onAbort");
413
+ signal?.addEventListener("abort", onAbort, {
414
+ once: true
415
+ });
416
+ });
417
+ }
418
+ async function fetchWithCoreDrainRetry(run, options = {}) {
419
+ const first = await run();
420
+ const delayMs = await readCoreDrainingRetryDelayMs(first);
421
+ if (delayMs === null) return first;
422
+ options.onRetry?.({
423
+ attempt: 1,
424
+ maxAttempts: 2,
425
+ delayMs
426
+ });
427
+ await first.body?.cancel();
428
+ await waitForCoreDrain(delayMs, options.signal);
429
+ return run();
430
+ }
373
431
  function resolveLuaJobTimeoutSeconds(timeout) {
374
432
  const resolved = timeout ?? LUA_JOB_DEFAULT_TIMEOUT_SECONDS;
375
433
  if (!Number.isInteger(resolved)) {
@@ -478,7 +536,7 @@ function isKnownProfile(profiles, profileId) {
478
536
  function hasCapability(profiles, profileId, required) {
479
537
  return capabilitiesFor(profiles, profileId).includes(required);
480
538
  }
481
- 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, DESKTOP_FILE_COMMANDS, DESKTOP_FILE_COMMAND_SET, REASONING_EFFORT_VALUES, IMPLICIT_MODEL_SELECTION_SOURCES, AGENT_NAME_TOKEN, DEFAULT_PERSONA_GUIDE, PERSONAL_SPACE_STARTING_PERSONA, 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, TEMPLATE_TRIGGER_URL_ENV_PREFIX, SUBJECT_TYPES, SubjectTypeSchema, CREDENTIAL_TYPES, CredentialTypeSchema, DEVICE_OPERATIONS, DeviceOperationSchema, DEVICE_SCOPE_BY_OPERATION, DeviceBindingSchema, IdSchema, PrincipalDescriptorSchema, ActorDescriptorSchema, PrincipalOwnerSchema, CredentialLifecycleSchema, GeneralCredentialDescriptorSchema, DeviceCredentialDescriptorSchema, GeneralPrincipalContextSchema, DeviceCredentialPrincipalContextSchema, RawPrincipalContextSchema, PrincipalContextSchema, DeviceCredentialClaimSchema, LUA_CLIENT_HEADER, LUA_CLIENT_APPS, SEMVER_PATTERN, WEB_RELEASE_PATTERN, CLIENT_HEADER_PATTERN, AUTHZ_PROJECTION_VERSION, ProjectedScopeSchema, DisplayRoleSchema, AuthorizationPrincipalSchema, CredentialContextSchema, ProjectionAnomalySchema, ProjectedOrgSchema, ProjectedResourceSchema, CapabilityProfilesSchema, RoleCatalogSchema, EffectiveAuthorizationSchema, ResourcePageSchema;
539
+ 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, DESKTOP_FILE_COMMANDS, DESKTOP_FILE_COMMAND_SET, REASONING_EFFORT_VALUES, IMPLICIT_MODEL_SELECTION_SOURCES, AGENT_NAME_TOKEN, DEFAULT_PERSONA_GUIDE, PERSONAL_SPACE_STARTING_PERSONA, CORE_DRAINING_CODE, CORE_DRAINING_DEFAULT_RETRY_MS, CORE_DRAINING_MAX_RETRY_MS, 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, TEMPLATE_TRIGGER_URL_ENV_PREFIX, SUBJECT_TYPES, SubjectTypeSchema, CREDENTIAL_TYPES, CredentialTypeSchema, DEVICE_OPERATIONS, DeviceOperationSchema, DEVICE_SCOPE_BY_OPERATION, DeviceBindingSchema, IdSchema, PrincipalDescriptorSchema, ActorDescriptorSchema, PrincipalOwnerSchema, CredentialLifecycleSchema, GeneralCredentialDescriptorSchema, DeviceCredentialDescriptorSchema, GeneralPrincipalContextSchema, DeviceCredentialPrincipalContextSchema, RawPrincipalContextSchema, PrincipalContextSchema, DeviceCredentialClaimSchema, LUA_CLIENT_HEADER, LUA_CLIENT_APPS, SEMVER_PATTERN, WEB_RELEASE_PATTERN, CLIENT_HEADER_PATTERN, AUTHZ_PROJECTION_VERSION, ProjectedScopeSchema, DisplayRoleSchema, AuthorizationPrincipalSchema, CredentialContextSchema, ProjectionAnomalySchema, ProjectedOrgSchema, ProjectedResourceSchema, CapabilityProfilesSchema, RoleCatalogSchema, EffectiveAuthorizationSchema, ResourcePageSchema;
482
540
  var init_dist = __esm({
483
541
  "../shared-types/dist/index.mjs"() {
484
542
  "use strict";
@@ -892,6 +950,21 @@ This text is who you are for this person. As you learn them, their name, their w
892
950
  `;
893
951
  __name(buildPersonalSpaceStartingPersona, "buildPersonalSpaceStartingPersona");
894
952
  __name2(buildPersonalSpaceStartingPersona, "buildPersonalSpaceStartingPersona");
953
+ CORE_DRAINING_CODE = "CORE_DRAINING";
954
+ CORE_DRAINING_DEFAULT_RETRY_MS = 1e3;
955
+ CORE_DRAINING_MAX_RETRY_MS = 5e3;
956
+ __name(isRecord, "isRecord");
957
+ __name2(isRecord, "isRecord");
958
+ __name(isCoreDrainingErrorResponse, "isCoreDrainingErrorResponse");
959
+ __name2(isCoreDrainingErrorResponse, "isCoreDrainingErrorResponse");
960
+ __name(coreDrainingRetryDelayMs, "coreDrainingRetryDelayMs");
961
+ __name2(coreDrainingRetryDelayMs, "coreDrainingRetryDelayMs");
962
+ __name(readCoreDrainingRetryDelayMs, "readCoreDrainingRetryDelayMs");
963
+ __name2(readCoreDrainingRetryDelayMs, "readCoreDrainingRetryDelayMs");
964
+ __name(waitForCoreDrain, "waitForCoreDrain");
965
+ __name2(waitForCoreDrain, "waitForCoreDrain");
966
+ __name(fetchWithCoreDrainRetry, "fetchWithCoreDrainRetry");
967
+ __name2(fetchWithCoreDrainRetry, "fetchWithCoreDrainRetry");
895
968
  VoiceNameSchema = z.string().regex(/^[a-zA-Z0-9_-]+$/, "Voice name must contain only alphanumeric characters, underscores, or hyphens").min(1).max(64);
896
969
  PluginProviderSchema = z.enum([
897
970
  "deepgram",
@@ -1617,20 +1690,40 @@ var init_lua_fetch = __esm({
1617
1690
  });
1618
1691
 
1619
1692
  // src/services/firebase-session.ts
1693
+ import { z as z4 } from "zod";
1620
1694
  function requireFirebaseWebApiKey() {
1621
1695
  if (!FIREBASE_WEB_API_KEY) {
1622
1696
  throw new Error("Firebase sign-in is not configured for this CLI build.");
1623
1697
  }
1624
1698
  return FIREBASE_WEB_API_KEY;
1625
1699
  }
1700
+ function uidFromFirebaseIdToken(idToken) {
1701
+ const segments = idToken.split(".");
1702
+ if (segments.length !== 3 || !segments[1]) throw new Error(INVALID_FIREBASE_SESSION);
1703
+ let payload;
1704
+ try {
1705
+ payload = JSON.parse(Buffer.from(segments[1], "base64url").toString("utf8"));
1706
+ } catch {
1707
+ throw new Error(INVALID_FIREBASE_SESSION);
1708
+ }
1709
+ const parsed = firebaseIdTokenPayloadSchema.safeParse(payload);
1710
+ if (parsed.success) return parsed.data.sub;
1711
+ throw new Error(INVALID_FIREBASE_SESSION);
1712
+ }
1626
1713
  function parseFirebaseSession(json, now = Date.now()) {
1627
- const idToken = json.idToken ?? json.id_token;
1628
- const refreshToken = json.refreshToken ?? json.refresh_token;
1629
- const expiresIn = Number(json.expiresIn ?? json.expires_in);
1630
- const uid = json.localId ?? json.user_id;
1631
- if (typeof idToken !== "string" || idToken.length === 0 || typeof refreshToken !== "string" || refreshToken.length === 0 || typeof uid !== "string" || uid.length === 0 || !Number.isFinite(expiresIn) || expiresIn <= 0) {
1632
- throw new Error("Sign-in failed because Firebase returned an invalid session.");
1714
+ const customTokenResponse = customTokenResponseSchema.safeParse(json);
1715
+ if (customTokenResponse.success) {
1716
+ const { idToken: idToken2, refreshToken: refreshToken2, expiresIn: expiresIn2, localId } = customTokenResponse.data;
1717
+ return {
1718
+ idToken: idToken2,
1719
+ refreshToken: refreshToken2,
1720
+ expiresAt: now + expiresIn2 * 1e3,
1721
+ uid: localId ?? uidFromFirebaseIdToken(idToken2)
1722
+ };
1633
1723
  }
1724
+ const refreshResponse = refreshResponseSchema.safeParse(json);
1725
+ if (!refreshResponse.success) throw new Error(INVALID_FIREBASE_SESSION);
1726
+ const { id_token: idToken, refresh_token: refreshToken, expires_in: expiresIn, user_id: uid } = refreshResponse.data;
1634
1727
  return {
1635
1728
  idToken,
1636
1729
  refreshToken,
@@ -1687,14 +1780,31 @@ async function refreshFirebaseSession(session) {
1687
1780
  if (refreshed.uid !== session.uid) throw new Error("Firebase session refresh returned a different identity.");
1688
1781
  return refreshed;
1689
1782
  }
1690
- var FIREBASE_REFRESH_URL, FIREBASE_REQUEST_TIMEOUT_MS;
1783
+ var FIREBASE_REFRESH_URL, FIREBASE_REQUEST_TIMEOUT_MS, INVALID_FIREBASE_SESSION, customTokenResponseSchema, refreshResponseSchema, firebaseIdTokenPayloadSchema;
1691
1784
  var init_firebase_session = __esm({
1692
1785
  "src/services/firebase-session.ts"() {
1693
1786
  "use strict";
1694
1787
  init_constants();
1695
1788
  FIREBASE_REFRESH_URL = "https://securetoken.googleapis.com/v1/token";
1696
1789
  FIREBASE_REQUEST_TIMEOUT_MS = 15e3;
1790
+ INVALID_FIREBASE_SESSION = "Sign-in failed because Firebase returned an invalid session.";
1791
+ customTokenResponseSchema = z4.object({
1792
+ idToken: z4.string().min(1),
1793
+ refreshToken: z4.string().min(1),
1794
+ expiresIn: z4.coerce.number().positive().finite(),
1795
+ localId: z4.string().min(1).optional()
1796
+ });
1797
+ refreshResponseSchema = z4.object({
1798
+ id_token: z4.string().min(1),
1799
+ refresh_token: z4.string().min(1),
1800
+ expires_in: z4.coerce.number().positive().finite(),
1801
+ user_id: z4.string().min(1)
1802
+ });
1803
+ firebaseIdTokenPayloadSchema = z4.object({
1804
+ sub: z4.string().min(1)
1805
+ });
1697
1806
  __name(requireFirebaseWebApiKey, "requireFirebaseWebApiKey");
1807
+ __name(uidFromFirebaseIdToken, "uidFromFirebaseIdToken");
1698
1808
  __name(parseFirebaseSession, "parseFirebaseSession");
1699
1809
  __name(parseFirebaseError, "parseFirebaseError");
1700
1810
  __name(fetchFirebase, "fetchFirebase");
@@ -1706,7 +1816,7 @@ var init_firebase_session = __esm({
1706
1816
  import { createHash, randomUUID } from "crypto";
1707
1817
  import { mkdir, open, readFile, rename, unlink } from "fs/promises";
1708
1818
  import { join as join3 } from "path";
1709
- import { z as z4 } from "zod";
1819
+ import { z as z5 } from "zod";
1710
1820
  function environmentKey(environment) {
1711
1821
  return createHash("sha256").update(`${environment.apiUrl}
1712
1822
  ${environment.authUrl}
@@ -1720,15 +1830,15 @@ var init_firebase_session_store = __esm({
1720
1830
  "src/services/firebase-session-store.ts"() {
1721
1831
  "use strict";
1722
1832
  init_constants();
1723
- storedFirebaseSessionSchema = z4.object({
1724
- version: z4.literal(1),
1725
- kind: z4.literal("firebase-session"),
1726
- generation: z4.string().min(1),
1727
- refreshToken: z4.string().min(1),
1728
- firebaseUid: z4.string().min(1),
1729
- apiUrl: z4.string().url(),
1730
- authUrl: z4.string().url(),
1731
- firebaseWebApiKey: z4.string().min(1)
1833
+ storedFirebaseSessionSchema = z5.object({
1834
+ version: z5.literal(1),
1835
+ kind: z5.literal("firebase-session"),
1836
+ generation: z5.string().min(1),
1837
+ refreshToken: z5.string().min(1),
1838
+ firebaseUid: z5.string().min(1),
1839
+ apiUrl: z5.string().url(),
1840
+ authUrl: z5.string().url(),
1841
+ firebaseWebApiKey: z5.string().min(1)
1732
1842
  });
1733
1843
  currentFirebaseSessionEnvironment = /* @__PURE__ */ __name(() => ({
1734
1844
  apiUrl: BASE_URLS.API,
@@ -1967,12 +2077,25 @@ import { randomUUID as randomUUID2 } from "crypto";
1967
2077
  function parseRetryAfter(raw) {
1968
2078
  if (!raw) return void 0;
1969
2079
  const seconds = Number.parseInt(raw, 10);
1970
- return Number.isFinite(seconds) && seconds > 0 ? seconds : void 0;
2080
+ return Number.isFinite(seconds) && seconds >= 0 ? seconds : void 0;
2081
+ }
2082
+ function isCoreDrainApiError(error) {
2083
+ if (!error || error.statusCode !== 503) return false;
2084
+ return isCoreDrainingErrorResponse({
2085
+ error: error.error
2086
+ });
2087
+ }
2088
+ function coreDrainApiRetryDelayMs(error) {
2089
+ const retryAfterSeconds = error?.retryAfterSeconds;
2090
+ if (retryAfterSeconds === void 0) return CORE_DRAINING_DEFAULT_RETRY_MS;
2091
+ const delayMs = retryAfterSeconds * 1e3;
2092
+ return Math.min(Math.max(0, delayMs), CORE_DRAINING_MAX_RETRY_MS);
1971
2093
  }
1972
2094
  var HttpClient;
1973
2095
  var init_http_client = __esm({
1974
2096
  "src/api/http.client.ts"() {
1975
2097
  "use strict";
2098
+ init_dist();
1976
2099
  init_auth_error();
1977
2100
  init_lua_fetch();
1978
2101
  init_request_credential();
@@ -2191,6 +2314,12 @@ Check that your Lua login has access to this agent or organization.`);
2191
2314
  headers
2192
2315
  }, 0);
2193
2316
  }
2317
+ async httpPostCoreDrainRetry(url, data, headers) {
2318
+ const first = await this.httpPostOnce(url, data, headers);
2319
+ if (!isCoreDrainApiError(first.error)) return first;
2320
+ await new Promise((resolve) => setTimeout(resolve, coreDrainApiRetryDelayMs(first.error)));
2321
+ return this.httpPostOnce(url, data, headers);
2322
+ }
2194
2323
  /**
2195
2324
  * Performs an HTTP PUT request
2196
2325
  * @param url - The relative URL path to request (will be appended to baseUrl)
@@ -2236,6 +2365,8 @@ Check that your Lua login has access to this agent or organization.`);
2236
2365
  }
2237
2366
  };
2238
2367
  __name(parseRetryAfter, "parseRetryAfter");
2368
+ __name(isCoreDrainApiError, "isCoreDrainApiError");
2369
+ __name(coreDrainApiRetryDelayMs, "coreDrainApiRetryDelayMs");
2239
2370
  }
2240
2371
  });
2241
2372
 
@@ -6010,7 +6141,7 @@ var init_agents_api_service = __esm({
6010
6141
  });
6011
6142
  if (body.identifier) query.set("identifier", body.identifier);
6012
6143
  const chatBody = this.toChatGenerateBody(body);
6013
- return this.httpPost(`/chat/generate/${targetAgentId}?${query.toString()}`, chatBody, {});
6144
+ return this.httpPostCoreDrainRetry(`/chat/generate/${targetAgentId}?${query.toString()}`, chatBody, {});
6014
6145
  }
6015
6146
  /**
6016
6147
  * Sandbox overload: mirrors the `AI.generate` pattern where the simplified