@dudousxd/nestjs-agent-react 0.19.0 → 0.20.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/media.cjs ADDED
@@ -0,0 +1,155 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
7
+ var __export = (target, all) => {
8
+ for (var name in all)
9
+ __defProp(target, name, { get: all[name], enumerable: true });
10
+ };
11
+ var __copyProps = (to, from, except, desc) => {
12
+ if (from && typeof from === "object" || typeof from === "function") {
13
+ for (let key of __getOwnPropNames(from))
14
+ if (!__hasOwnProp.call(to, key) && key !== except)
15
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
16
+ }
17
+ return to;
18
+ };
19
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
20
+
21
+ // src/media/index.ts
22
+ var media_exports = {};
23
+ __export(media_exports, {
24
+ MediaUploadError: () => MediaUploadError,
25
+ createMediaUpload: () => createMediaUpload,
26
+ mediaAttachments: () => mediaAttachments,
27
+ withMediaUploads: () => withMediaUploads
28
+ });
29
+ module.exports = __toCommonJS(media_exports);
30
+ var import_nestjs_media_client = require("@dudousxd/nestjs-media-client");
31
+ function mediaAttachments(options = {}) {
32
+ return (file, uploadOptions, connection) => createMediaUpload({
33
+ ...options,
34
+ baseUrl: connection.baseUrl,
35
+ getHeaders: connection.headers,
36
+ fetch: connection.fetch,
37
+ ...connection.credentials !== void 0 ? {
38
+ credentials: connection.credentials
39
+ } : {}
40
+ })(file, uploadOptions);
41
+ }
42
+ __name(mediaAttachments, "mediaAttachments");
43
+ var MediaUploadError = class extends Error {
44
+ static {
45
+ __name(this, "MediaUploadError");
46
+ }
47
+ status;
48
+ method;
49
+ path;
50
+ constructor(status, method, path, statusText) {
51
+ super(`Attachment upload failed: ${method} ${path} \u2192 ${status} ${statusText}`), this.status = status, this.method = method, this.path = path;
52
+ this.name = "MediaUploadError";
53
+ }
54
+ };
55
+ function createMediaUpload(options = {}) {
56
+ const origin = (options.baseUrl ?? "").replace(/\/$/, "");
57
+ const base = `${origin}${(options.path ?? "/agent").replace(/\/$/, "")}/attachments/uploads`;
58
+ const baseFetch = /* @__PURE__ */ __name(() => options.fetch ?? fetch, "baseFetch");
59
+ const fetchWithCredentials = /* @__PURE__ */ __name((input, init) => baseFetch()(input, {
60
+ ...init,
61
+ ...options.credentials !== void 0 ? {
62
+ credentials: options.credentials
63
+ } : {}
64
+ }), "fetchWithCredentials");
65
+ const headers = /* @__PURE__ */ __name(async () => ({
66
+ ...options.headers,
67
+ ...await options.getHeaders?.() ?? {}
68
+ }), "headers");
69
+ const discard = /* @__PURE__ */ __name((mediaId) => {
70
+ void (async () => {
71
+ await fetchWithCredentials(`${base}/${encodeURIComponent(mediaId)}`, {
72
+ method: "DELETE",
73
+ headers: await headers()
74
+ });
75
+ })().catch(() => void 0);
76
+ }, "discard");
77
+ const call = /* @__PURE__ */ __name(async (method, url, body) => {
78
+ const response = await fetchWithCredentials(url, {
79
+ method,
80
+ headers: {
81
+ accept: "application/json",
82
+ ...body !== void 0 ? {
83
+ "content-type": "application/json"
84
+ } : {},
85
+ ...await headers()
86
+ },
87
+ ...body !== void 0 ? {
88
+ body: JSON.stringify(body)
89
+ } : {}
90
+ });
91
+ if (!response.ok) {
92
+ throw new MediaUploadError(response.status, method, url, response.statusText);
93
+ }
94
+ return await response.json();
95
+ }, "call");
96
+ return async (file, { signal, onProgress } = {}) => {
97
+ signal?.throwIfAborted();
98
+ const begun = await call("POST", base, {
99
+ filename: file.name,
100
+ contentType: file.type,
101
+ size: file.size
102
+ });
103
+ const onAbort = /* @__PURE__ */ __name(() => discard(begun.mediaId), "onAbort");
104
+ signal?.addEventListener("abort", onAbort, {
105
+ once: true
106
+ });
107
+ try {
108
+ const location = /^https?:\/\//.test(begun.location) ? begun.location : `${origin}${begun.location}`;
109
+ await (0, import_nestjs_media_client.streamChunks)(location, file, {
110
+ resume: false,
111
+ fetchImpl: fetchWithCredentials,
112
+ getHeaders: headers,
113
+ ...options.chunkSize !== void 0 ? {
114
+ chunkSize: options.chunkSize
115
+ } : {},
116
+ ...options.retries !== void 0 ? {
117
+ retries: options.retries
118
+ } : {},
119
+ ...signal !== void 0 ? {
120
+ signal
121
+ } : {},
122
+ onProgress: /* @__PURE__ */ __name((sent, total) => onProgress?.(total > 0 ? sent / total : 1), "onProgress")
123
+ });
124
+ signal?.throwIfAborted();
125
+ const attachment = await call("POST", `${base}/${encodeURIComponent(begun.mediaId)}/complete`);
126
+ onProgress?.(1);
127
+ return attachment;
128
+ } catch (error) {
129
+ if (!signal?.aborted) discard(begun.mediaId);
130
+ throw error;
131
+ } finally {
132
+ signal?.removeEventListener("abort", onAbort);
133
+ }
134
+ };
135
+ }
136
+ __name(createMediaUpload, "createMediaUpload");
137
+ function withMediaUploads(backend, options = {}) {
138
+ const upload = createMediaUpload(options);
139
+ return new Proxy(backend, {
140
+ get(target, property) {
141
+ if (property === "uploadAttachment") return upload;
142
+ const value = Reflect.get(target, property, target);
143
+ return typeof value === "function" ? value.bind(target) : value;
144
+ }
145
+ });
146
+ }
147
+ __name(withMediaUploads, "withMediaUploads");
148
+ // Annotate the CommonJS export names for ESM import in node:
149
+ 0 && (module.exports = {
150
+ MediaUploadError,
151
+ createMediaUpload,
152
+ mediaAttachments,
153
+ withMediaUploads
154
+ });
155
+ //# sourceMappingURL=media.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/media/index.ts"],"sourcesContent":["import type { MessageAttachment } from '@dudousxd/nestjs-agent-core';\nimport { streamChunks } from '@dudousxd/nestjs-media-client';\nimport type {\n AgentBackend,\n AttachmentUploadStrategy,\n UploadAttachmentOptions,\n} from '../backend.js';\nimport type { AgentClientOptions } from '../client.js';\n\n/** Tuning for {@link mediaAttachments}; every field optional. */\nexport interface MediaAttachmentsOptions {\n /** The agent's route prefix (`AgentModule`'s `path`, global prefix included). Default `/agent`. */\n path?: string;\n /** Bytes per tus `PATCH`. Default 5 MiB. */\n chunkSize?: number;\n /** Attempts per chunk before the upload fails. Default 3. */\n retries?: number;\n}\n\n/**\n * Resumable attachment uploads through `@dudousxd/nestjs-media`, in one line:\n *\n * ```ts\n * const chat = useAgentChat({ attachments: mediaAttachments() });\n * const files = useAttachments({ backend: chat.backend });\n * ```\n *\n * Reuses the chat client's own connection (base url, headers, credentials), so it needs no\n * configuration. Also takes `new AgentClient({ attachments: mediaAttachments() })`.\n */\nexport function mediaAttachments(options: MediaAttachmentsOptions = {}): AttachmentUploadStrategy {\n return (file, uploadOptions, connection) =>\n createMediaUpload({\n ...options,\n baseUrl: connection.baseUrl,\n getHeaders: connection.headers,\n fetch: connection.fetch,\n ...(connection.credentials !== undefined ? { credentials: connection.credentials } : {}),\n })(file, uploadOptions);\n}\n\n/**\n * Where and how {@link createMediaUpload} talks to the server. The connection fields are\n * {@link AgentClientOptions}' — pass the same ones your `AgentClient` gets, so the tus requests\n * carry the same cookies / CSRF header / bearer token as the rest of the chat.\n */\nexport interface MediaUploadOptions extends AgentClientOptions {\n /** The agent's route prefix (`AgentModule`'s `path`, global prefix included). Default `/agent`. */\n path?: string;\n /** Bytes per tus `PATCH`. Default 5 MiB (nestjs-media-client's default). */\n chunkSize?: number;\n /** Attempts per chunk before the upload fails. Default 3. */\n retries?: number;\n}\n\n/** What `useAttachments({ upload })` and `AgentBackend.uploadAttachment` both take. */\nexport type AttachmentUpload = (\n file: File,\n options?: UploadAttachmentOptions,\n) => Promise<MessageAttachment>;\n\n/**\n * A non-2xx answer from the agent's upload routes. Carries `status` like `AgentHttpError` does\n * (413 too large, 415 type refused, 404 not yours) — its own class because this subpath is bundled\n * apart from the root entry, where an `instanceof AgentHttpError` would not match a copy.\n */\nexport class MediaUploadError extends Error {\n constructor(\n readonly status: number,\n readonly method: string,\n readonly path: string,\n statusText: string,\n ) {\n super(`Attachment upload failed: ${method} ${path} → ${status} ${statusText}`);\n this.name = 'MediaUploadError';\n }\n}\n\ninterface BeginResponse {\n mediaId: string;\n location: string;\n}\n\n/**\n * A resumable `upload` for `useAttachments`, backed by `@dudousxd/nestjs-media` on the server\n * (`AgentMediaAttachmentsModule` from `@dudousxd/nestjs-agent/media`):\n *\n * 1. `POST <path>/attachments/uploads` — the agent validates the file and opens a tus session the\n * actor owns;\n * 2. the bytes stream to nestjs-media's own tus endpoint in chunks (`streamChunks`), reporting\n * progress and honouring the abort signal;\n * 3. `POST <path>/attachments/uploads/:mediaId/complete` — the agent confirms the bytes landed and\n * answers the `MessageAttachment` the turn will reference by `mediaId`.\n *\n * An aborted or failed upload is discarded server-side (`DELETE`), best effort.\n */\nexport function createMediaUpload(options: MediaUploadOptions = {}): AttachmentUpload {\n const origin = (options.baseUrl ?? '').replace(/\\/$/, '');\n const base = `${origin}${(options.path ?? '/agent').replace(/\\/$/, '')}/attachments/uploads`;\n const baseFetch = (): typeof fetch => options.fetch ?? fetch;\n // Every request — the agent's and media's tus PATCHes — rides the same credentials mode.\n const fetchWithCredentials: typeof fetch = (input, init) =>\n baseFetch()(input, {\n ...init,\n ...(options.credentials !== undefined ? { credentials: options.credentials } : {}),\n });\n const headers = async (): Promise<Record<string, string>> => ({\n ...options.headers,\n ...((await options.getHeaders?.()) ?? {}),\n });\n const discard = (mediaId: string): void => {\n void (async () => {\n await fetchWithCredentials(`${base}/${encodeURIComponent(mediaId)}`, {\n method: 'DELETE',\n headers: await headers(),\n });\n })().catch(() => undefined);\n };\n const call = async <T>(method: string, url: string, body?: unknown): Promise<T> => {\n const response = await fetchWithCredentials(url, {\n method,\n headers: {\n accept: 'application/json',\n ...(body !== undefined ? { 'content-type': 'application/json' } : {}),\n ...(await headers()),\n },\n ...(body !== undefined ? { body: JSON.stringify(body) } : {}),\n });\n if (!response.ok) {\n throw new MediaUploadError(response.status, method, url, response.statusText);\n }\n return (await response.json()) as T;\n };\n\n return async (file, { signal, onProgress } = {}) => {\n signal?.throwIfAborted();\n const begun = await call<BeginResponse>('POST', base, {\n filename: file.name,\n contentType: file.type,\n size: file.size,\n });\n const onAbort = () => discard(begun.mediaId);\n signal?.addEventListener('abort', onAbort, { once: true });\n try {\n const location = /^https?:\\/\\//.test(begun.location)\n ? begun.location\n : `${origin}${begun.location}`;\n await streamChunks(location, file, {\n resume: false,\n fetchImpl: fetchWithCredentials,\n getHeaders: headers,\n ...(options.chunkSize !== undefined ? { chunkSize: options.chunkSize } : {}),\n ...(options.retries !== undefined ? { retries: options.retries } : {}),\n ...(signal !== undefined ? { signal } : {}),\n onProgress: (sent, total) => onProgress?.(total > 0 ? sent / total : 1),\n });\n signal?.throwIfAborted();\n const attachment = await call<MessageAttachment>(\n 'POST',\n `${base}/${encodeURIComponent(begun.mediaId)}/complete`,\n );\n onProgress?.(1);\n return attachment;\n } catch (error) {\n if (!signal?.aborted) discard(begun.mediaId);\n throw error;\n } finally {\n signal?.removeEventListener('abort', onAbort);\n }\n };\n}\n\n/**\n * Plug media uploads in once: the same backend, with `uploadAttachment` replaced by\n * {@link createMediaUpload}. Hand the result to `useAgentChat({ backend })` and\n * `useAttachments({ backend })` and every composer uploads resumably — no per-composer wiring.\n *\n * ```ts\n * const backend = withMediaUploads(new AgentClient(connection), connection);\n * ```\n *\n * Every other member is the original backend's, still bound to it.\n */\nexport function withMediaUploads<B extends AgentBackend>(\n backend: B,\n options: MediaUploadOptions = {},\n): B {\n const upload = createMediaUpload(options);\n return new Proxy(backend, {\n get(target, property) {\n if (property === 'uploadAttachment') return upload;\n const value: unknown = Reflect.get(target, property, target);\n return typeof value === 'function' ? value.bind(target) : value;\n },\n });\n}\n"],"mappings":"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","names":["mediaAttachments","options","file","uploadOptions","connection","createMediaUpload","baseUrl","getHeaders","headers","fetch","credentials","undefined","MediaUploadError","Error","status","method","path","statusText","name","origin","replace","base","baseFetch","fetchWithCredentials","input","init","discard","mediaId","encodeURIComponent","catch","call","url","body","response","accept","JSON","stringify","ok","json","signal","onProgress","throwIfAborted","begun","filename","contentType","type","size","onAbort","addEventListener","once","location","test","streamChunks","resume","fetchImpl","chunkSize","retries","sent","total","attachment","error","aborted","removeEventListener","withMediaUploads","backend","upload","Proxy","get","target","property","value","Reflect","bind"]}
@@ -0,0 +1,78 @@
1
+ import { MessageAttachment } from '@dudousxd/nestjs-agent-core';
2
+ import { U as UploadAttachmentOptions, d as AgentClientOptions, b as AttachmentUploadStrategy, A as AgentBackend } from './client-0Wd-WPsu.cjs';
3
+
4
+ /** Tuning for {@link mediaAttachments}; every field optional. */
5
+ interface MediaAttachmentsOptions {
6
+ /** The agent's route prefix (`AgentModule`'s `path`, global prefix included). Default `/agent`. */
7
+ path?: string;
8
+ /** Bytes per tus `PATCH`. Default 5 MiB. */
9
+ chunkSize?: number;
10
+ /** Attempts per chunk before the upload fails. Default 3. */
11
+ retries?: number;
12
+ }
13
+ /**
14
+ * Resumable attachment uploads through `@dudousxd/nestjs-media`, in one line:
15
+ *
16
+ * ```ts
17
+ * const chat = useAgentChat({ attachments: mediaAttachments() });
18
+ * const files = useAttachments({ backend: chat.backend });
19
+ * ```
20
+ *
21
+ * Reuses the chat client's own connection (base url, headers, credentials), so it needs no
22
+ * configuration. Also takes `new AgentClient({ attachments: mediaAttachments() })`.
23
+ */
24
+ declare function mediaAttachments(options?: MediaAttachmentsOptions): AttachmentUploadStrategy;
25
+ /**
26
+ * Where and how {@link createMediaUpload} talks to the server. The connection fields are
27
+ * {@link AgentClientOptions}' — pass the same ones your `AgentClient` gets, so the tus requests
28
+ * carry the same cookies / CSRF header / bearer token as the rest of the chat.
29
+ */
30
+ interface MediaUploadOptions extends AgentClientOptions {
31
+ /** The agent's route prefix (`AgentModule`'s `path`, global prefix included). Default `/agent`. */
32
+ path?: string;
33
+ /** Bytes per tus `PATCH`. Default 5 MiB (nestjs-media-client's default). */
34
+ chunkSize?: number;
35
+ /** Attempts per chunk before the upload fails. Default 3. */
36
+ retries?: number;
37
+ }
38
+ /** What `useAttachments({ upload })` and `AgentBackend.uploadAttachment` both take. */
39
+ type AttachmentUpload = (file: File, options?: UploadAttachmentOptions) => Promise<MessageAttachment>;
40
+ /**
41
+ * A non-2xx answer from the agent's upload routes. Carries `status` like `AgentHttpError` does
42
+ * (413 too large, 415 type refused, 404 not yours) — its own class because this subpath is bundled
43
+ * apart from the root entry, where an `instanceof AgentHttpError` would not match a copy.
44
+ */
45
+ declare class MediaUploadError extends Error {
46
+ readonly status: number;
47
+ readonly method: string;
48
+ readonly path: string;
49
+ constructor(status: number, method: string, path: string, statusText: string);
50
+ }
51
+ /**
52
+ * A resumable `upload` for `useAttachments`, backed by `@dudousxd/nestjs-media` on the server
53
+ * (`AgentMediaAttachmentsModule` from `@dudousxd/nestjs-agent/media`):
54
+ *
55
+ * 1. `POST <path>/attachments/uploads` — the agent validates the file and opens a tus session the
56
+ * actor owns;
57
+ * 2. the bytes stream to nestjs-media's own tus endpoint in chunks (`streamChunks`), reporting
58
+ * progress and honouring the abort signal;
59
+ * 3. `POST <path>/attachments/uploads/:mediaId/complete` — the agent confirms the bytes landed and
60
+ * answers the `MessageAttachment` the turn will reference by `mediaId`.
61
+ *
62
+ * An aborted or failed upload is discarded server-side (`DELETE`), best effort.
63
+ */
64
+ declare function createMediaUpload(options?: MediaUploadOptions): AttachmentUpload;
65
+ /**
66
+ * Plug media uploads in once: the same backend, with `uploadAttachment` replaced by
67
+ * {@link createMediaUpload}. Hand the result to `useAgentChat({ backend })` and
68
+ * `useAttachments({ backend })` and every composer uploads resumably — no per-composer wiring.
69
+ *
70
+ * ```ts
71
+ * const backend = withMediaUploads(new AgentClient(connection), connection);
72
+ * ```
73
+ *
74
+ * Every other member is the original backend's, still bound to it.
75
+ */
76
+ declare function withMediaUploads<B extends AgentBackend>(backend: B, options?: MediaUploadOptions): B;
77
+
78
+ export { type AttachmentUpload, type MediaAttachmentsOptions, MediaUploadError, type MediaUploadOptions, createMediaUpload, mediaAttachments, withMediaUploads };
@@ -0,0 +1,78 @@
1
+ import { MessageAttachment } from '@dudousxd/nestjs-agent-core';
2
+ import { U as UploadAttachmentOptions, d as AgentClientOptions, b as AttachmentUploadStrategy, A as AgentBackend } from './client-0Wd-WPsu.js';
3
+
4
+ /** Tuning for {@link mediaAttachments}; every field optional. */
5
+ interface MediaAttachmentsOptions {
6
+ /** The agent's route prefix (`AgentModule`'s `path`, global prefix included). Default `/agent`. */
7
+ path?: string;
8
+ /** Bytes per tus `PATCH`. Default 5 MiB. */
9
+ chunkSize?: number;
10
+ /** Attempts per chunk before the upload fails. Default 3. */
11
+ retries?: number;
12
+ }
13
+ /**
14
+ * Resumable attachment uploads through `@dudousxd/nestjs-media`, in one line:
15
+ *
16
+ * ```ts
17
+ * const chat = useAgentChat({ attachments: mediaAttachments() });
18
+ * const files = useAttachments({ backend: chat.backend });
19
+ * ```
20
+ *
21
+ * Reuses the chat client's own connection (base url, headers, credentials), so it needs no
22
+ * configuration. Also takes `new AgentClient({ attachments: mediaAttachments() })`.
23
+ */
24
+ declare function mediaAttachments(options?: MediaAttachmentsOptions): AttachmentUploadStrategy;
25
+ /**
26
+ * Where and how {@link createMediaUpload} talks to the server. The connection fields are
27
+ * {@link AgentClientOptions}' — pass the same ones your `AgentClient` gets, so the tus requests
28
+ * carry the same cookies / CSRF header / bearer token as the rest of the chat.
29
+ */
30
+ interface MediaUploadOptions extends AgentClientOptions {
31
+ /** The agent's route prefix (`AgentModule`'s `path`, global prefix included). Default `/agent`. */
32
+ path?: string;
33
+ /** Bytes per tus `PATCH`. Default 5 MiB (nestjs-media-client's default). */
34
+ chunkSize?: number;
35
+ /** Attempts per chunk before the upload fails. Default 3. */
36
+ retries?: number;
37
+ }
38
+ /** What `useAttachments({ upload })` and `AgentBackend.uploadAttachment` both take. */
39
+ type AttachmentUpload = (file: File, options?: UploadAttachmentOptions) => Promise<MessageAttachment>;
40
+ /**
41
+ * A non-2xx answer from the agent's upload routes. Carries `status` like `AgentHttpError` does
42
+ * (413 too large, 415 type refused, 404 not yours) — its own class because this subpath is bundled
43
+ * apart from the root entry, where an `instanceof AgentHttpError` would not match a copy.
44
+ */
45
+ declare class MediaUploadError extends Error {
46
+ readonly status: number;
47
+ readonly method: string;
48
+ readonly path: string;
49
+ constructor(status: number, method: string, path: string, statusText: string);
50
+ }
51
+ /**
52
+ * A resumable `upload` for `useAttachments`, backed by `@dudousxd/nestjs-media` on the server
53
+ * (`AgentMediaAttachmentsModule` from `@dudousxd/nestjs-agent/media`):
54
+ *
55
+ * 1. `POST <path>/attachments/uploads` — the agent validates the file and opens a tus session the
56
+ * actor owns;
57
+ * 2. the bytes stream to nestjs-media's own tus endpoint in chunks (`streamChunks`), reporting
58
+ * progress and honouring the abort signal;
59
+ * 3. `POST <path>/attachments/uploads/:mediaId/complete` — the agent confirms the bytes landed and
60
+ * answers the `MessageAttachment` the turn will reference by `mediaId`.
61
+ *
62
+ * An aborted or failed upload is discarded server-side (`DELETE`), best effort.
63
+ */
64
+ declare function createMediaUpload(options?: MediaUploadOptions): AttachmentUpload;
65
+ /**
66
+ * Plug media uploads in once: the same backend, with `uploadAttachment` replaced by
67
+ * {@link createMediaUpload}. Hand the result to `useAgentChat({ backend })` and
68
+ * `useAttachments({ backend })` and every composer uploads resumably — no per-composer wiring.
69
+ *
70
+ * ```ts
71
+ * const backend = withMediaUploads(new AgentClient(connection), connection);
72
+ * ```
73
+ *
74
+ * Every other member is the original backend's, still bound to it.
75
+ */
76
+ declare function withMediaUploads<B extends AgentBackend>(backend: B, options?: MediaUploadOptions): B;
77
+
78
+ export { type AttachmentUpload, type MediaAttachmentsOptions, MediaUploadError, type MediaUploadOptions, createMediaUpload, mediaAttachments, withMediaUploads };
package/dist/media.js ADDED
@@ -0,0 +1,129 @@
1
+ var __defProp = Object.defineProperty;
2
+ var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
3
+
4
+ // src/media/index.ts
5
+ import { streamChunks } from "@dudousxd/nestjs-media-client";
6
+ function mediaAttachments(options = {}) {
7
+ return (file, uploadOptions, connection) => createMediaUpload({
8
+ ...options,
9
+ baseUrl: connection.baseUrl,
10
+ getHeaders: connection.headers,
11
+ fetch: connection.fetch,
12
+ ...connection.credentials !== void 0 ? {
13
+ credentials: connection.credentials
14
+ } : {}
15
+ })(file, uploadOptions);
16
+ }
17
+ __name(mediaAttachments, "mediaAttachments");
18
+ var MediaUploadError = class extends Error {
19
+ static {
20
+ __name(this, "MediaUploadError");
21
+ }
22
+ status;
23
+ method;
24
+ path;
25
+ constructor(status, method, path, statusText) {
26
+ super(`Attachment upload failed: ${method} ${path} \u2192 ${status} ${statusText}`), this.status = status, this.method = method, this.path = path;
27
+ this.name = "MediaUploadError";
28
+ }
29
+ };
30
+ function createMediaUpload(options = {}) {
31
+ const origin = (options.baseUrl ?? "").replace(/\/$/, "");
32
+ const base = `${origin}${(options.path ?? "/agent").replace(/\/$/, "")}/attachments/uploads`;
33
+ const baseFetch = /* @__PURE__ */ __name(() => options.fetch ?? fetch, "baseFetch");
34
+ const fetchWithCredentials = /* @__PURE__ */ __name((input, init) => baseFetch()(input, {
35
+ ...init,
36
+ ...options.credentials !== void 0 ? {
37
+ credentials: options.credentials
38
+ } : {}
39
+ }), "fetchWithCredentials");
40
+ const headers = /* @__PURE__ */ __name(async () => ({
41
+ ...options.headers,
42
+ ...await options.getHeaders?.() ?? {}
43
+ }), "headers");
44
+ const discard = /* @__PURE__ */ __name((mediaId) => {
45
+ void (async () => {
46
+ await fetchWithCredentials(`${base}/${encodeURIComponent(mediaId)}`, {
47
+ method: "DELETE",
48
+ headers: await headers()
49
+ });
50
+ })().catch(() => void 0);
51
+ }, "discard");
52
+ const call = /* @__PURE__ */ __name(async (method, url, body) => {
53
+ const response = await fetchWithCredentials(url, {
54
+ method,
55
+ headers: {
56
+ accept: "application/json",
57
+ ...body !== void 0 ? {
58
+ "content-type": "application/json"
59
+ } : {},
60
+ ...await headers()
61
+ },
62
+ ...body !== void 0 ? {
63
+ body: JSON.stringify(body)
64
+ } : {}
65
+ });
66
+ if (!response.ok) {
67
+ throw new MediaUploadError(response.status, method, url, response.statusText);
68
+ }
69
+ return await response.json();
70
+ }, "call");
71
+ return async (file, { signal, onProgress } = {}) => {
72
+ signal?.throwIfAborted();
73
+ const begun = await call("POST", base, {
74
+ filename: file.name,
75
+ contentType: file.type,
76
+ size: file.size
77
+ });
78
+ const onAbort = /* @__PURE__ */ __name(() => discard(begun.mediaId), "onAbort");
79
+ signal?.addEventListener("abort", onAbort, {
80
+ once: true
81
+ });
82
+ try {
83
+ const location = /^https?:\/\//.test(begun.location) ? begun.location : `${origin}${begun.location}`;
84
+ await streamChunks(location, file, {
85
+ resume: false,
86
+ fetchImpl: fetchWithCredentials,
87
+ getHeaders: headers,
88
+ ...options.chunkSize !== void 0 ? {
89
+ chunkSize: options.chunkSize
90
+ } : {},
91
+ ...options.retries !== void 0 ? {
92
+ retries: options.retries
93
+ } : {},
94
+ ...signal !== void 0 ? {
95
+ signal
96
+ } : {},
97
+ onProgress: /* @__PURE__ */ __name((sent, total) => onProgress?.(total > 0 ? sent / total : 1), "onProgress")
98
+ });
99
+ signal?.throwIfAborted();
100
+ const attachment = await call("POST", `${base}/${encodeURIComponent(begun.mediaId)}/complete`);
101
+ onProgress?.(1);
102
+ return attachment;
103
+ } catch (error) {
104
+ if (!signal?.aborted) discard(begun.mediaId);
105
+ throw error;
106
+ } finally {
107
+ signal?.removeEventListener("abort", onAbort);
108
+ }
109
+ };
110
+ }
111
+ __name(createMediaUpload, "createMediaUpload");
112
+ function withMediaUploads(backend, options = {}) {
113
+ const upload = createMediaUpload(options);
114
+ return new Proxy(backend, {
115
+ get(target, property) {
116
+ if (property === "uploadAttachment") return upload;
117
+ const value = Reflect.get(target, property, target);
118
+ return typeof value === "function" ? value.bind(target) : value;
119
+ }
120
+ });
121
+ }
122
+ __name(withMediaUploads, "withMediaUploads");
123
+ export {
124
+ MediaUploadError,
125
+ createMediaUpload,
126
+ mediaAttachments,
127
+ withMediaUploads
128
+ };
129
+ //# sourceMappingURL=media.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/media/index.ts"],"sourcesContent":["import type { MessageAttachment } from '@dudousxd/nestjs-agent-core';\nimport { streamChunks } from '@dudousxd/nestjs-media-client';\nimport type {\n AgentBackend,\n AttachmentUploadStrategy,\n UploadAttachmentOptions,\n} from '../backend.js';\nimport type { AgentClientOptions } from '../client.js';\n\n/** Tuning for {@link mediaAttachments}; every field optional. */\nexport interface MediaAttachmentsOptions {\n /** The agent's route prefix (`AgentModule`'s `path`, global prefix included). Default `/agent`. */\n path?: string;\n /** Bytes per tus `PATCH`. Default 5 MiB. */\n chunkSize?: number;\n /** Attempts per chunk before the upload fails. Default 3. */\n retries?: number;\n}\n\n/**\n * Resumable attachment uploads through `@dudousxd/nestjs-media`, in one line:\n *\n * ```ts\n * const chat = useAgentChat({ attachments: mediaAttachments() });\n * const files = useAttachments({ backend: chat.backend });\n * ```\n *\n * Reuses the chat client's own connection (base url, headers, credentials), so it needs no\n * configuration. Also takes `new AgentClient({ attachments: mediaAttachments() })`.\n */\nexport function mediaAttachments(options: MediaAttachmentsOptions = {}): AttachmentUploadStrategy {\n return (file, uploadOptions, connection) =>\n createMediaUpload({\n ...options,\n baseUrl: connection.baseUrl,\n getHeaders: connection.headers,\n fetch: connection.fetch,\n ...(connection.credentials !== undefined ? { credentials: connection.credentials } : {}),\n })(file, uploadOptions);\n}\n\n/**\n * Where and how {@link createMediaUpload} talks to the server. The connection fields are\n * {@link AgentClientOptions}' — pass the same ones your `AgentClient` gets, so the tus requests\n * carry the same cookies / CSRF header / bearer token as the rest of the chat.\n */\nexport interface MediaUploadOptions extends AgentClientOptions {\n /** The agent's route prefix (`AgentModule`'s `path`, global prefix included). Default `/agent`. */\n path?: string;\n /** Bytes per tus `PATCH`. Default 5 MiB (nestjs-media-client's default). */\n chunkSize?: number;\n /** Attempts per chunk before the upload fails. Default 3. */\n retries?: number;\n}\n\n/** What `useAttachments({ upload })` and `AgentBackend.uploadAttachment` both take. */\nexport type AttachmentUpload = (\n file: File,\n options?: UploadAttachmentOptions,\n) => Promise<MessageAttachment>;\n\n/**\n * A non-2xx answer from the agent's upload routes. Carries `status` like `AgentHttpError` does\n * (413 too large, 415 type refused, 404 not yours) — its own class because this subpath is bundled\n * apart from the root entry, where an `instanceof AgentHttpError` would not match a copy.\n */\nexport class MediaUploadError extends Error {\n constructor(\n readonly status: number,\n readonly method: string,\n readonly path: string,\n statusText: string,\n ) {\n super(`Attachment upload failed: ${method} ${path} → ${status} ${statusText}`);\n this.name = 'MediaUploadError';\n }\n}\n\ninterface BeginResponse {\n mediaId: string;\n location: string;\n}\n\n/**\n * A resumable `upload` for `useAttachments`, backed by `@dudousxd/nestjs-media` on the server\n * (`AgentMediaAttachmentsModule` from `@dudousxd/nestjs-agent/media`):\n *\n * 1. `POST <path>/attachments/uploads` — the agent validates the file and opens a tus session the\n * actor owns;\n * 2. the bytes stream to nestjs-media's own tus endpoint in chunks (`streamChunks`), reporting\n * progress and honouring the abort signal;\n * 3. `POST <path>/attachments/uploads/:mediaId/complete` — the agent confirms the bytes landed and\n * answers the `MessageAttachment` the turn will reference by `mediaId`.\n *\n * An aborted or failed upload is discarded server-side (`DELETE`), best effort.\n */\nexport function createMediaUpload(options: MediaUploadOptions = {}): AttachmentUpload {\n const origin = (options.baseUrl ?? '').replace(/\\/$/, '');\n const base = `${origin}${(options.path ?? '/agent').replace(/\\/$/, '')}/attachments/uploads`;\n const baseFetch = (): typeof fetch => options.fetch ?? fetch;\n // Every request — the agent's and media's tus PATCHes — rides the same credentials mode.\n const fetchWithCredentials: typeof fetch = (input, init) =>\n baseFetch()(input, {\n ...init,\n ...(options.credentials !== undefined ? { credentials: options.credentials } : {}),\n });\n const headers = async (): Promise<Record<string, string>> => ({\n ...options.headers,\n ...((await options.getHeaders?.()) ?? {}),\n });\n const discard = (mediaId: string): void => {\n void (async () => {\n await fetchWithCredentials(`${base}/${encodeURIComponent(mediaId)}`, {\n method: 'DELETE',\n headers: await headers(),\n });\n })().catch(() => undefined);\n };\n const call = async <T>(method: string, url: string, body?: unknown): Promise<T> => {\n const response = await fetchWithCredentials(url, {\n method,\n headers: {\n accept: 'application/json',\n ...(body !== undefined ? { 'content-type': 'application/json' } : {}),\n ...(await headers()),\n },\n ...(body !== undefined ? { body: JSON.stringify(body) } : {}),\n });\n if (!response.ok) {\n throw new MediaUploadError(response.status, method, url, response.statusText);\n }\n return (await response.json()) as T;\n };\n\n return async (file, { signal, onProgress } = {}) => {\n signal?.throwIfAborted();\n const begun = await call<BeginResponse>('POST', base, {\n filename: file.name,\n contentType: file.type,\n size: file.size,\n });\n const onAbort = () => discard(begun.mediaId);\n signal?.addEventListener('abort', onAbort, { once: true });\n try {\n const location = /^https?:\\/\\//.test(begun.location)\n ? begun.location\n : `${origin}${begun.location}`;\n await streamChunks(location, file, {\n resume: false,\n fetchImpl: fetchWithCredentials,\n getHeaders: headers,\n ...(options.chunkSize !== undefined ? { chunkSize: options.chunkSize } : {}),\n ...(options.retries !== undefined ? { retries: options.retries } : {}),\n ...(signal !== undefined ? { signal } : {}),\n onProgress: (sent, total) => onProgress?.(total > 0 ? sent / total : 1),\n });\n signal?.throwIfAborted();\n const attachment = await call<MessageAttachment>(\n 'POST',\n `${base}/${encodeURIComponent(begun.mediaId)}/complete`,\n );\n onProgress?.(1);\n return attachment;\n } catch (error) {\n if (!signal?.aborted) discard(begun.mediaId);\n throw error;\n } finally {\n signal?.removeEventListener('abort', onAbort);\n }\n };\n}\n\n/**\n * Plug media uploads in once: the same backend, with `uploadAttachment` replaced by\n * {@link createMediaUpload}. Hand the result to `useAgentChat({ backend })` and\n * `useAttachments({ backend })` and every composer uploads resumably — no per-composer wiring.\n *\n * ```ts\n * const backend = withMediaUploads(new AgentClient(connection), connection);\n * ```\n *\n * Every other member is the original backend's, still bound to it.\n */\nexport function withMediaUploads<B extends AgentBackend>(\n backend: B,\n options: MediaUploadOptions = {},\n): B {\n const upload = createMediaUpload(options);\n return new Proxy(backend, {\n get(target, property) {\n if (property === 'uploadAttachment') return upload;\n const value: unknown = Reflect.get(target, property, target);\n return typeof value === 'function' ? value.bind(target) : value;\n },\n });\n}\n"],"mappings":"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","names":["streamChunks","mediaAttachments","options","file","uploadOptions","connection","createMediaUpload","baseUrl","getHeaders","headers","fetch","credentials","undefined","MediaUploadError","Error","status","method","path","statusText","name","origin","replace","base","baseFetch","fetchWithCredentials","input","init","discard","mediaId","encodeURIComponent","catch","call","url","body","response","accept","JSON","stringify","ok","json","signal","onProgress","throwIfAborted","begun","filename","contentType","type","size","onAbort","addEventListener","once","location","test","streamChunks","resume","fetchImpl","chunkSize","retries","sent","total","attachment","error","aborted","removeEventListener","withMediaUploads","backend","upload","Proxy","get","target","property","value","Reflect","bind"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dudousxd/nestjs-agent-react",
3
- "version": "0.19.0",
3
+ "version": "0.20.0",
4
4
  "repository": {
5
5
  "type": "git",
6
6
  "url": "git+https://github.com/DavideCarvalho/nestjs-agent.git",
@@ -67,6 +67,16 @@
67
67
  "types": "./dist/genui-json-render.d.cts",
68
68
  "default": "./dist/genui-json-render.cjs"
69
69
  }
70
+ },
71
+ "./media": {
72
+ "import": {
73
+ "types": "./dist/media.d.ts",
74
+ "default": "./dist/media.js"
75
+ },
76
+ "require": {
77
+ "types": "./dist/media.d.cts",
78
+ "default": "./dist/media.cjs"
79
+ }
70
80
  }
71
81
  },
72
82
  "files": [
@@ -77,6 +87,7 @@
77
87
  },
78
88
  "peerDependencies": {
79
89
  "@ai-sdk/react": "^4.0.0",
90
+ "@dudousxd/nestjs-media-client": ">=0.3.0",
80
91
  "@json-render/react": ">=0.21.0 <1.0.0",
81
92
  "@streamdown/code": "^1.1.1",
82
93
  "@streamdown/math": "^1.0.2",
@@ -94,6 +105,9 @@
94
105
  "unist-util-visit": "^5.1.0"
95
106
  },
96
107
  "peerDependenciesMeta": {
108
+ "@dudousxd/nestjs-media-client": {
109
+ "optional": true
110
+ },
97
111
  "@json-render/react": {
98
112
  "optional": true
99
113
  },
@@ -136,6 +150,7 @@
136
150
  },
137
151
  "devDependencies": {
138
152
  "@ai-sdk/react": "4.0.17",
153
+ "@dudousxd/nestjs-media-client": "0.3.0",
139
154
  "@json-render/core": "0.21.0",
140
155
  "@json-render/react": "0.21.0",
141
156
  "@streamdown/code": "1.1.1",