@gullabs/google 0.8.3 → 0.9.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.
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
@@ -409,6 +409,11 @@ function mapPart(p) {
409
409
  ...p.mediaResolution !== void 0 ? { mediaResolution: { level: mapMediaResolution(p.mediaResolution) } } : {}
410
410
  };
411
411
  }
412
+ case "file-ref":
413
+ throw new LlmError(
414
+ "Google Gemini expects FileUriPart with a Files API uri; got file-ref (provider file id). Upload via GoogleFileStore and pass the returned uri.",
415
+ { kind: "bad_request", retryable: false, provider: "google" }
416
+ );
412
417
  default:
413
418
  return assertNever(p);
414
419
  }
@@ -2866,25 +2871,88 @@ var GoogleFileStore = class {
2866
2871
  }
2867
2872
  }
2868
2873
  /**
2869
- * Delete a single uploaded file.
2870
- * 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`.
2871
2881
  */
2872
- 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;
2873
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
+ }
2874
2900
  const client = await this.getClient();
2875
- await client.delete({ name: handle.name });
2901
+ await client.delete({ name });
2876
2902
  } catch (err) {
2877
- 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);
2878
2919
  }
2879
2920
  }
2880
2921
  /**
2881
2922
  * Delete multiple files.
2882
- * 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.
2883
2927
  */
2884
- async deleteAll(handles) {
2885
- 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)));
2886
2934
  }
2887
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
+ }
2888
2956
  var DEFAULT_SKEW_SECONDS = 30;
2889
2957
  var DEFAULT_EXTENSION_SECONDS = 3600;
2890
2958
  async function buildCachesClient(auth) {