@gullabs/xai 0.3.0 → 0.4.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.ts CHANGED
@@ -338,6 +338,21 @@ interface XaiFileListResult {
338
338
  files: XaiFileHandle[];
339
339
  paginationToken?: string;
340
340
  }
341
+ /**
342
+ * Options for {@link XaiFileStore.delete} / {@link XaiFileStore.deleteAll}.
343
+ *
344
+ * Default is fail-open (P5 side-effect style). Pass `failClosed: true` when
345
+ * the host gates durable state (e.g. `released_at`) on known delete success.
346
+ */
347
+ interface FileDeleteOptions {
348
+ signal?: AbortSignal;
349
+ /**
350
+ * When true, non-404 failures throw typed `LlmError`.
351
+ * When false/omitted, non-404 failures invoke `onDeleteError` and resolve.
352
+ * HTTP 404 is success in both modes (idempotent).
353
+ */
354
+ failClosed?: boolean;
355
+ }
341
356
  interface XaiFileStoreOptions {
342
357
  auth: AuthMaterial;
343
358
  /** Default {@link XAI_FILES_DEFAULT_BASE_URL}. */
@@ -381,13 +396,23 @@ declare class XaiFileStore {
381
396
  list(opts?: XaiFileListOptions, signal?: AbortSignal): Promise<XaiFileListResult>;
382
397
  /**
383
398
  * Delete a file. Idempotent: HTTP 404 → success.
384
- * Other errors are forwarded to `onDeleteError` and **not** rethrown (P5).
399
+ *
400
+ * Default (`failClosed` omitted/false): non-404 errors go to `onDeleteError`
401
+ * and resolve (P5 fail-open). With `failClosed: true`, non-404 errors throw
402
+ * typed `LlmError` and `onDeleteError` is not called.
403
+ *
404
+ * Empty/blank ids always throw `bad_request` (caller fault).
385
405
  */
386
- delete(fileIdOrHandle: string | Pick<XaiFileHandle, 'id'>, signal?: AbortSignal): Promise<void>;
406
+ delete(fileIdOrHandle: string | Pick<XaiFileHandle, 'id'>, opts?: FileDeleteOptions): Promise<void>;
387
407
  /**
388
- * Delete many files. Each failure is individually fail-open; none are thrown.
408
+ * Delete many files.
409
+ *
410
+ * Fail-open (default): `Promise.allSettled` — each failure → `onDeleteError`.
411
+ * Fail-closed: `Promise.all` — first throw rejects; in-flight siblings are
412
+ * not cancelled (partial deletes may already have succeeded at the provider).
413
+ * Prefer per-id delete + host DB mark when gating durable release state.
389
414
  */
390
- deleteAll(ids: ReadonlyArray<string | Pick<XaiFileHandle, 'id'>>, signal?: AbortSignal): Promise<void>;
415
+ deleteAll(ids: ReadonlyArray<string | Pick<XaiFileHandle, 'id'>>, opts?: FileDeleteOptions): Promise<void>;
391
416
  /** Download raw file bytes. */
392
417
  getContent(fileId: string, signal?: AbortSignal): Promise<Uint8Array>;
393
418
  }
@@ -566,4 +591,4 @@ declare function xaiPricingSource(): PricingSource;
566
591
  */
567
592
  declare function xaiProvider(opts?: XaiAdapterOptions): ProviderPlugin;
568
593
 
569
- export { Grok45ConfigSchema, XAI_FILES_DEFAULT_BASE_URL, XAI_FILE_MAX_BYTES, XAI_FILE_TTL_MAX_SECONDS, XAI_FILE_TTL_MIN_SECONDS, XAI_PRICING, type XaiAdapterOptions, type XaiClientLike, type XaiFileHandle, type XaiFileListOptions, type XaiFileListResult, XaiFileStore, type XaiFileStoreOptions, type XaiFileUploadInput, type XaiInputContentPart, type XaiInputFilePart, type XaiInputImagePart, type XaiInputItem, type XaiInputTextPart, type XaiMessageOutputItem, type XaiModelRates, type XaiOutputItem, type XaiOutputTextPart, type XaiProviderOptions, type XaiReasoningOutputItem, type XaiReasoningSummaryPart, type XaiResponseCreateParams, type XaiResponseShape, type XaiTextFormat, type XaiUsageShape, buildXaiClient, classifyXaiError, computeXaiCost, grok45ModelDescriptor, requireApiKey, xaiAdapter, xaiModelDescriptors, xaiPricingSource, xaiPricingVersion, xaiProvider, xaiRegistry };
594
+ export { type FileDeleteOptions, Grok45ConfigSchema, XAI_FILES_DEFAULT_BASE_URL, XAI_FILE_MAX_BYTES, XAI_FILE_TTL_MAX_SECONDS, XAI_FILE_TTL_MIN_SECONDS, XAI_PRICING, type XaiAdapterOptions, type XaiClientLike, type XaiFileHandle, type XaiFileListOptions, type XaiFileListResult, XaiFileStore, type XaiFileStoreOptions, type XaiFileUploadInput, type XaiInputContentPart, type XaiInputFilePart, type XaiInputImagePart, type XaiInputItem, type XaiInputTextPart, type XaiMessageOutputItem, type XaiModelRates, type XaiOutputItem, type XaiOutputTextPart, type XaiProviderOptions, type XaiReasoningOutputItem, type XaiReasoningSummaryPart, type XaiResponseCreateParams, type XaiResponseShape, type XaiTextFormat, type XaiUsageShape, buildXaiClient, classifyXaiError, computeXaiCost, grok45ModelDescriptor, requireApiKey, xaiAdapter, xaiModelDescriptors, xaiPricingSource, xaiPricingVersion, xaiProvider, xaiRegistry };
package/dist/index.js CHANGED
@@ -737,35 +737,25 @@ var XaiFileStore = class {
737
737
  }
738
738
  /**
739
739
  * Delete a file. Idempotent: HTTP 404 → success.
740
- * Other errors are forwarded to `onDeleteError` and **not** rethrown (P5).
740
+ *
741
+ * Default (`failClosed` omitted/false): non-404 errors go to `onDeleteError`
742
+ * and resolve (P5 fail-open). With `failClosed: true`, non-404 errors throw
743
+ * typed `LlmError` and `onDeleteError` is not called.
744
+ *
745
+ * Empty/blank ids always throw `bad_request` (caller fault).
741
746
  */
742
- async delete(fileIdOrHandle, signal) {
747
+ async delete(fileIdOrHandle, opts) {
743
748
  const fileId = resolveFileId(fileIdOrHandle);
744
749
  if (typeof fileId !== "string" || fileId.trim() === "") {
745
- this.onDeleteError(String(fileId), badRequest("fileId must be a non-empty string."));
746
- return;
750
+ throw badRequest("fileId must be a non-empty string.");
747
751
  }
752
+ const failClosed = opts?.failClosed === true;
753
+ const signal = opts?.signal;
748
754
  try {
749
- let res;
750
- try {
751
- res = await this.fetchImpl(
752
- this.filesUrl(fileId),
753
- this.requestInit("DELETE", signal !== void 0 ? { signal } : {})
754
- );
755
- } catch (e) {
756
- if (signal?.aborted === true) {
757
- this.onDeleteError(
758
- fileId,
759
- new LlmError("xAI file delete aborted", {
760
- kind: "aborted",
761
- retryable: false,
762
- provider: "xai"
763
- })
764
- );
765
- return;
766
- }
767
- throw e;
768
- }
755
+ const res = await this.fetchImpl(
756
+ this.filesUrl(fileId),
757
+ this.requestInit("DELETE", signal !== void 0 ? { signal } : {})
758
+ );
769
759
  if (res.status === 404) {
770
760
  return;
771
761
  }
@@ -776,14 +766,32 @@ var XaiFileStore = class {
776
766
  if (isNotFoundError(err)) {
777
767
  return;
778
768
  }
779
- this.onDeleteError(fileId, classifyStoreError(err));
769
+ const classified = signal?.aborted === true && !(err instanceof LlmError) ? new LlmError("xAI file delete aborted", {
770
+ kind: "aborted",
771
+ retryable: false,
772
+ provider: "xai",
773
+ cause: err
774
+ }) : classifyStoreError(err);
775
+ if (failClosed) {
776
+ throw classified;
777
+ }
778
+ this.onDeleteError(fileId, classified);
780
779
  }
781
780
  }
782
781
  /**
783
- * Delete many files. Each failure is individually fail-open; none are thrown.
782
+ * Delete many files.
783
+ *
784
+ * Fail-open (default): `Promise.allSettled` — each failure → `onDeleteError`.
785
+ * Fail-closed: `Promise.all` — first throw rejects; in-flight siblings are
786
+ * not cancelled (partial deletes may already have succeeded at the provider).
787
+ * Prefer per-id delete + host DB mark when gating durable release state.
784
788
  */
785
- async deleteAll(ids, signal) {
786
- await Promise.allSettled(ids.map((id) => this.delete(id, signal)));
789
+ async deleteAll(ids, opts) {
790
+ if (opts?.failClosed === true) {
791
+ await Promise.all(ids.map((id) => this.delete(id, opts)));
792
+ return;
793
+ }
794
+ await Promise.allSettled(ids.map((id) => this.delete(id, opts)));
787
795
  }
788
796
  /** Download raw file bytes. */
789
797
  async getContent(fileId, signal) {