@mindstudio-ai/agent 0.1.108 → 0.1.109

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
@@ -109,6 +109,13 @@ declare class Store {
109
109
  get access(): FileAccess;
110
110
  /** Store bytes. Returns a {@link StoredFile} with a ready-to-use `url`. */
111
111
  put(content: Buffer | Uint8Array | string, options?: PutOptions): Promise<StoredFile>;
112
+ /**
113
+ * Large-content half of {@link put}: mint a presigned POST scoped to exactly
114
+ * these bytes and send them direct to storage — the JSON transport's body
115
+ * limit never sees them. Same result contract as the small path; the final
116
+ * `head` keeps the returned metadata honest (server-observed size/type/time).
117
+ */
118
+ private _putPresigned;
112
119
  /** Read an object's bytes (backend / trusted context). */
113
120
  get(key: string): Promise<Buffer>;
114
121
  /** Metadata without downloading. Rejects if the object doesn't exist. */
package/dist/index.js CHANGED
@@ -2592,6 +2592,7 @@ function toBase64(content) {
2592
2592
  typeof content === "string" ? Buffer.from(content) : content
2593
2593
  ).toString("base64");
2594
2594
  }
2595
+ var PRESIGN_THRESHOLD = 4 * 1024 * 1024;
2595
2596
  function extensionFor(filename) {
2596
2597
  if (!filename) {
2597
2598
  return "";
@@ -2619,16 +2620,73 @@ var Store = class {
2619
2620
  const ext = extensionFor(options?.filename);
2620
2621
  const key = options?.key ?? (options?.contentAddressed ? `${createHash("sha256").update(content).digest("hex")}${ext}` : `${randomUUID()}${ext}`);
2621
2622
  const cacheControl = options?.cacheControl ?? (!options?.key && this._access === "public" ? "public, max-age=31536000, immutable" : void 0);
2623
+ const bytes = typeof content === "string" ? Buffer.from(content) : content;
2624
+ if (bytes.byteLength >= PRESIGN_THRESHOLD) {
2625
+ return this._putPresigned(bytes, key, {
2626
+ ...options?.contentType ? { contentType: options.contentType } : {},
2627
+ ...cacheControl ? { cacheControl } : {}
2628
+ });
2629
+ }
2622
2630
  const meta = await this._call("put", {
2623
2631
  store: this._store,
2624
2632
  access: this._access,
2625
2633
  key,
2626
- body: toBase64(content),
2634
+ body: toBase64(bytes),
2627
2635
  ...options?.contentType ? { contentType: options.contentType } : {},
2628
2636
  ...cacheControl ? { cacheControl } : {}
2629
2637
  });
2630
2638
  return this._toFile(key, meta);
2631
2639
  }
2640
+ /**
2641
+ * Large-content half of {@link put}: mint a presigned POST scoped to exactly
2642
+ * these bytes and send them direct to storage — the JSON transport's body
2643
+ * limit never sees them. Same result contract as the small path; the final
2644
+ * `head` keeps the returned metadata honest (server-observed size/type/time).
2645
+ */
2646
+ async _putPresigned(bytes, key, options) {
2647
+ const res = await this._call("create-upload", {
2648
+ store: this._store,
2649
+ access: this._access,
2650
+ key,
2651
+ maxSize: bytes.byteLength,
2652
+ ...options.contentType ? { contentType: options.contentType } : {},
2653
+ ...options.cacheControl ? { cacheControl: options.cacheControl } : {}
2654
+ });
2655
+ const form = new FormData();
2656
+ for (const [k, v] of Object.entries(
2657
+ res.uploadFields
2658
+ )) {
2659
+ form.append(k, v);
2660
+ }
2661
+ const view = new Uint8Array(
2662
+ bytes.buffer,
2663
+ bytes.byteOffset,
2664
+ bytes.byteLength
2665
+ );
2666
+ form.append(
2667
+ "file",
2668
+ new Blob([view], options.contentType ? { type: options.contentType } : void 0)
2669
+ );
2670
+ const upload = await fetch(res.uploadUrl, {
2671
+ method: "POST",
2672
+ body: form
2673
+ });
2674
+ if (!upload.ok) {
2675
+ const errorText = await upload.text().catch(() => "");
2676
+ throw new MindStudioError(
2677
+ `Upload failed: ${upload.status} ${upload.statusText}${errorText ? ` \u2014 ${errorText.replace(/<[^>]*>/g, " ").replace(/\s+/g, " ").trim().slice(0, 200)}` : ""}`,
2678
+ "upload_error",
2679
+ upload.status,
2680
+ errorText || void 0
2681
+ );
2682
+ }
2683
+ const meta = await this._call("head", {
2684
+ store: this._store,
2685
+ access: this._access,
2686
+ key
2687
+ });
2688
+ return this._toFile(key, meta);
2689
+ }
2632
2690
  /** Read an object's bytes (backend / trusted context). */
2633
2691
  async get(key) {
2634
2692
  const res = await this._call("get", {