@gullabs/google 0.8.4 → 0.9.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.
package/dist/index.d.cts CHANGED
@@ -562,6 +562,22 @@ interface GeminiFilesClientLike {
562
562
  name: string;
563
563
  }): Promise<void>;
564
564
  }
565
+ /**
566
+ * Options for {@link GoogleFileStore.delete} / {@link GoogleFileStore.deleteAll}.
567
+ *
568
+ * Default is fail-open (P5 side-effect style). Pass `failClosed: true` when
569
+ * the host gates durable state on known delete success. Shape matches
570
+ * `@gullabs/xai` `FileDeleteOptions` by convention.
571
+ */
572
+ interface FileDeleteOptions {
573
+ signal?: AbortSignal;
574
+ /**
575
+ * When true, non-not-found failures throw typed `LlmError`.
576
+ * When false/omitted, failures invoke `onDeleteError` and resolve.
577
+ * Not-found is success in both modes (idempotent).
578
+ */
579
+ failClosed?: boolean;
580
+ }
565
581
  interface GoogleFileStoreOptions {
566
582
  auth: AuthMaterial;
567
583
  /** Injectable client for tests; skips SDK import when provided. */
@@ -617,15 +633,23 @@ declare class GoogleFileStore {
617
633
  signal?: AbortSignal;
618
634
  }): Promise<GoogleFileHandle>;
619
635
  /**
620
- * Delete a single uploaded file.
621
- * Errors are forwarded to `onDeleteError` and NOT rethrown.
636
+ * Delete a single uploaded file. Idempotent: not-found → success.
637
+ *
638
+ * Default (`failClosed` omitted/false): errors go to `onDeleteError` and
639
+ * resolve (P5 fail-open). With `failClosed: true`, non-not-found errors
640
+ * throw typed `LlmError` and `onDeleteError` is not called.
641
+ *
642
+ * Empty/blank `handle.name` always throws `bad_request`.
622
643
  */
623
- delete(handle: GoogleFileHandle): Promise<void>;
644
+ delete(handle: GoogleFileHandle, opts?: FileDeleteOptions): Promise<void>;
624
645
  /**
625
646
  * Delete multiple files.
626
- * Each failure is individually forwarded to `onDeleteError`; none are thrown.
647
+ *
648
+ * Fail-open (default): `Promise.allSettled` per handle.
649
+ * Fail-closed: `Promise.all` — first throw rejects; in-flight siblings are
650
+ * not cancelled. Prefer per-handle delete when gating durable release state.
627
651
  */
628
- deleteAll(handles: GoogleFileHandle[]): Promise<void>;
652
+ deleteAll(handles: GoogleFileHandle[], opts?: FileDeleteOptions): Promise<void>;
629
653
  }
630
654
 
631
655
  /**
@@ -937,4 +961,4 @@ interface GeminiContentToMessagesResult {
937
961
  */
938
962
  declare function geminiContentToMessages(input: GeminiContentToMessagesInput): GeminiContentToMessagesResult;
939
963
 
940
- export { type CacheKey, type Citation, FLEX_DEFAULT_TIMEOUT_MS, GEMINI_PRICING, type GeminiAdapterOptions, type GeminiCachesClientLike, type GeminiClientLike, type GeminiContentToMessagesInput, type GeminiContentToMessagesResult, type GeminiCountTokensParams, type GeminiCountTokensResponseShape, type GeminiFilesClientLike, type GoogleCacheHandle, GoogleCacheStore, type GoogleCacheStoreOptions, type GoogleFileHandle, GoogleFileStore, type GoogleFileStoreOptions, type GoogleProviderOptions, type GoogleSafetySetting, type GoogleSearchTool, STANDARD_DEFAULT_TIMEOUT_MS, TIER_FACTOR, TRANSPORT_TIMEOUT_BUFFER_MS, buildGoogleClient, defaultGeminiRegistry, geminiAdapter, geminiContentToMessages, geminiModelDescriptors, geminiPricingSource, gemmaModelDescriptors, googleProvider, isGeminiCapacityError, normalizeGroundingCitations, pricingVersion, requireApiKey };
964
+ export { type CacheKey, type Citation, FLEX_DEFAULT_TIMEOUT_MS, type FileDeleteOptions, GEMINI_PRICING, type GeminiAdapterOptions, type GeminiCachesClientLike, type GeminiClientLike, type GeminiContentToMessagesInput, type GeminiContentToMessagesResult, type GeminiCountTokensParams, type GeminiCountTokensResponseShape, type GeminiFilesClientLike, type GoogleCacheHandle, GoogleCacheStore, type GoogleCacheStoreOptions, type GoogleFileHandle, GoogleFileStore, type GoogleFileStoreOptions, type GoogleProviderOptions, type GoogleSafetySetting, type GoogleSearchTool, STANDARD_DEFAULT_TIMEOUT_MS, TIER_FACTOR, TRANSPORT_TIMEOUT_BUFFER_MS, buildGoogleClient, defaultGeminiRegistry, geminiAdapter, geminiContentToMessages, geminiModelDescriptors, geminiPricingSource, gemmaModelDescriptors, googleProvider, isGeminiCapacityError, normalizeGroundingCitations, pricingVersion, requireApiKey };
package/dist/index.d.ts CHANGED
@@ -562,6 +562,22 @@ interface GeminiFilesClientLike {
562
562
  name: string;
563
563
  }): Promise<void>;
564
564
  }
565
+ /**
566
+ * Options for {@link GoogleFileStore.delete} / {@link GoogleFileStore.deleteAll}.
567
+ *
568
+ * Default is fail-open (P5 side-effect style). Pass `failClosed: true` when
569
+ * the host gates durable state on known delete success. Shape matches
570
+ * `@gullabs/xai` `FileDeleteOptions` by convention.
571
+ */
572
+ interface FileDeleteOptions {
573
+ signal?: AbortSignal;
574
+ /**
575
+ * When true, non-not-found failures throw typed `LlmError`.
576
+ * When false/omitted, failures invoke `onDeleteError` and resolve.
577
+ * Not-found is success in both modes (idempotent).
578
+ */
579
+ failClosed?: boolean;
580
+ }
565
581
  interface GoogleFileStoreOptions {
566
582
  auth: AuthMaterial;
567
583
  /** Injectable client for tests; skips SDK import when provided. */
@@ -617,15 +633,23 @@ declare class GoogleFileStore {
617
633
  signal?: AbortSignal;
618
634
  }): Promise<GoogleFileHandle>;
619
635
  /**
620
- * Delete a single uploaded file.
621
- * Errors are forwarded to `onDeleteError` and NOT rethrown.
636
+ * Delete a single uploaded file. Idempotent: not-found → success.
637
+ *
638
+ * Default (`failClosed` omitted/false): errors go to `onDeleteError` and
639
+ * resolve (P5 fail-open). With `failClosed: true`, non-not-found errors
640
+ * throw typed `LlmError` and `onDeleteError` is not called.
641
+ *
642
+ * Empty/blank `handle.name` always throws `bad_request`.
622
643
  */
623
- delete(handle: GoogleFileHandle): Promise<void>;
644
+ delete(handle: GoogleFileHandle, opts?: FileDeleteOptions): Promise<void>;
624
645
  /**
625
646
  * Delete multiple files.
626
- * Each failure is individually forwarded to `onDeleteError`; none are thrown.
647
+ *
648
+ * Fail-open (default): `Promise.allSettled` per handle.
649
+ * Fail-closed: `Promise.all` — first throw rejects; in-flight siblings are
650
+ * not cancelled. Prefer per-handle delete when gating durable release state.
627
651
  */
628
- deleteAll(handles: GoogleFileHandle[]): Promise<void>;
652
+ deleteAll(handles: GoogleFileHandle[], opts?: FileDeleteOptions): Promise<void>;
629
653
  }
630
654
 
631
655
  /**
@@ -937,4 +961,4 @@ interface GeminiContentToMessagesResult {
937
961
  */
938
962
  declare function geminiContentToMessages(input: GeminiContentToMessagesInput): GeminiContentToMessagesResult;
939
963
 
940
- export { type CacheKey, type Citation, FLEX_DEFAULT_TIMEOUT_MS, GEMINI_PRICING, type GeminiAdapterOptions, type GeminiCachesClientLike, type GeminiClientLike, type GeminiContentToMessagesInput, type GeminiContentToMessagesResult, type GeminiCountTokensParams, type GeminiCountTokensResponseShape, type GeminiFilesClientLike, type GoogleCacheHandle, GoogleCacheStore, type GoogleCacheStoreOptions, type GoogleFileHandle, GoogleFileStore, type GoogleFileStoreOptions, type GoogleProviderOptions, type GoogleSafetySetting, type GoogleSearchTool, STANDARD_DEFAULT_TIMEOUT_MS, TIER_FACTOR, TRANSPORT_TIMEOUT_BUFFER_MS, buildGoogleClient, defaultGeminiRegistry, geminiAdapter, geminiContentToMessages, geminiModelDescriptors, geminiPricingSource, gemmaModelDescriptors, googleProvider, isGeminiCapacityError, normalizeGroundingCitations, pricingVersion, requireApiKey };
964
+ export { type CacheKey, type Citation, FLEX_DEFAULT_TIMEOUT_MS, type FileDeleteOptions, GEMINI_PRICING, type GeminiAdapterOptions, type GeminiCachesClientLike, type GeminiClientLike, type GeminiContentToMessagesInput, type GeminiContentToMessagesResult, type GeminiCountTokensParams, type GeminiCountTokensResponseShape, type GeminiFilesClientLike, type GoogleCacheHandle, GoogleCacheStore, type GoogleCacheStoreOptions, type GoogleFileHandle, GoogleFileStore, type GoogleFileStoreOptions, type GoogleProviderOptions, type GoogleSafetySetting, type GoogleSearchTool, STANDARD_DEFAULT_TIMEOUT_MS, TIER_FACTOR, TRANSPORT_TIMEOUT_BUFFER_MS, buildGoogleClient, defaultGeminiRegistry, geminiAdapter, geminiContentToMessages, geminiModelDescriptors, geminiPricingSource, gemmaModelDescriptors, googleProvider, isGeminiCapacityError, normalizeGroundingCitations, pricingVersion, requireApiKey };
package/dist/index.js CHANGED
@@ -2871,25 +2871,88 @@ var GoogleFileStore = class {
2871
2871
  }
2872
2872
  }
2873
2873
  /**
2874
- * Delete a single uploaded file.
2875
- * Errors are forwarded to `onDeleteError` and NOT rethrown.
2874
+ * Delete a single uploaded file. Idempotent: not-found → success.
2875
+ *
2876
+ * Default (`failClosed` omitted/false): errors go to `onDeleteError` and
2877
+ * resolve (P5 fail-open). With `failClosed: true`, non-not-found errors
2878
+ * throw typed `LlmError` and `onDeleteError` is not called.
2879
+ *
2880
+ * Empty/blank `handle.name` always throws `bad_request`.
2876
2881
  */
2877
- async delete(handle) {
2882
+ async delete(handle, opts) {
2883
+ const name = handle.name;
2884
+ if (typeof name !== "string" || name.trim() === "") {
2885
+ throw new LlmError("GoogleFileHandle.name must be a non-empty string.", {
2886
+ kind: "bad_request",
2887
+ retryable: false,
2888
+ provider: "google"
2889
+ });
2890
+ }
2891
+ const failClosed = opts?.failClosed === true;
2878
2892
  try {
2893
+ if (opts?.signal?.aborted === true) {
2894
+ throw new LlmError("Google file delete aborted", {
2895
+ kind: "aborted",
2896
+ retryable: false,
2897
+ provider: "google"
2898
+ });
2899
+ }
2879
2900
  const client = await this.getClient();
2880
- await client.delete({ name: handle.name });
2901
+ await client.delete({ name });
2881
2902
  } catch (err) {
2882
- this.onDeleteError(handle.name, err);
2903
+ if (isGoogleNotFoundError(err)) {
2904
+ return;
2905
+ }
2906
+ const classified = err instanceof LlmError ? err : classifyError(err);
2907
+ const withProvider = classified.provider === void 0 ? new LlmError(classified.message, {
2908
+ kind: classified.kind,
2909
+ retryable: classified.retryable,
2910
+ ...classified.httpStatus !== void 0 ? { httpStatus: classified.httpStatus } : {},
2911
+ ...classified.retryAfterMs !== void 0 ? { retryAfterMs: classified.retryAfterMs } : {},
2912
+ provider: "google",
2913
+ cause: classified.cause ?? err
2914
+ }) : classified;
2915
+ if (failClosed) {
2916
+ throw withProvider;
2917
+ }
2918
+ this.onDeleteError(name, withProvider);
2883
2919
  }
2884
2920
  }
2885
2921
  /**
2886
2922
  * Delete multiple files.
2887
- * Each failure is individually forwarded to `onDeleteError`; none are thrown.
2923
+ *
2924
+ * Fail-open (default): `Promise.allSettled` per handle.
2925
+ * Fail-closed: `Promise.all` — first throw rejects; in-flight siblings are
2926
+ * not cancelled. Prefer per-handle delete when gating durable release state.
2888
2927
  */
2889
- async deleteAll(handles) {
2890
- await Promise.allSettled(handles.map((h) => this.delete(h)));
2928
+ async deleteAll(handles, opts) {
2929
+ if (opts?.failClosed === true) {
2930
+ await Promise.all(handles.map((h) => this.delete(h, opts)));
2931
+ return;
2932
+ }
2933
+ await Promise.allSettled(handles.map((h) => this.delete(h, opts)));
2891
2934
  }
2892
2935
  };
2936
+ function isGoogleNotFoundError(err) {
2937
+ if (err instanceof LlmError && err.httpStatus === 404) {
2938
+ return true;
2939
+ }
2940
+ if (typeof err !== "object" || err === null) {
2941
+ return false;
2942
+ }
2943
+ const obj = err;
2944
+ if (obj["status"] === 404 || obj["httpStatus"] === 404 || obj["code"] === 404) {
2945
+ return true;
2946
+ }
2947
+ if (obj["status"] === "NOT_FOUND" || obj["code"] === "NOT_FOUND") {
2948
+ return true;
2949
+ }
2950
+ const msg = typeof obj["message"] === "string" ? obj["message"] : "";
2951
+ if (/not\s*found|404/i.test(msg) && /file/i.test(msg)) {
2952
+ return true;
2953
+ }
2954
+ return false;
2955
+ }
2893
2956
  var DEFAULT_SKEW_SECONDS = 30;
2894
2957
  var DEFAULT_EXTENSION_SECONDS = 3600;
2895
2958
  async function buildCachesClient(auth) {