@artooi/ag-ui-web-component 0.5.0 → 0.6.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/CHANGELOG.md CHANGED
@@ -7,6 +7,34 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
7
7
 
8
8
  ## [Unreleased]
9
9
 
10
+ ## [0.6.0] — 2026-06-25
11
+
12
+ ### Added
13
+
14
+ - **File uploads.** Set `data-attachments-url` (django-ag-ui's `AttachmentsView`)
15
+ to reveal a 📎 picker + drag-and-drop on the composer. Each file uploads
16
+ out-of-band (multipart, with the element's `headers`) into a pending tray —
17
+ one chip per file with a progress bar, settling to `ready` or `error` (with
18
+ retry / remove). On send, the ready files' refs render as read-only chips on
19
+ the user bubble and travel to the agent: the wire stays vanilla AG-UI (only
20
+ lightweight `{ id, name, mime, size }` refs, never bytes), the model learns the
21
+ ids from a one-line run-context manifest, and reads contents server-side via
22
+ the `read_attachment` tool. Refs persist on the message, so a restored
23
+ conversation re-renders its chips.
24
+ - **Client-side guards** (instant feedback; the server stays authoritative):
25
+ `data-attachment-accept` (an `<input accept>` list) and
26
+ `data-attachment-max-bytes` (default 10 MiB, `0` disables).
27
+ - **Pluggable upload transport.** A new `uploadHandler` property —
28
+ `(file, onProgress) => Promise<AttachmentRef>` — swaps the built-in multipart
29
+ upload for a custom one (a resumable `tus-js-client` adapter, direct-to-S3
30
+ multipart, …) without touching the tray, chips, or AG-UI wire. When set, the
31
+ 📎 affordance appears even with no `data-attachments-url`. Defaults to the
32
+ built-in `uploadAttachment`.
33
+ - **New exports:** `uploadAttachment` + `UploadOptions` + `UploadHandler`, the
34
+ `AttachmentRef` type, and `messageAttachments`. `AgUiClient.send` gains an
35
+ optional second `attachments` argument; the `ag-ui-submit` event `detail` now
36
+ also carries `attachments`.
37
+
10
38
  ## [0.5.0] — 2026-06-24
11
39
 
12
40
  ### Added
@@ -269,7 +297,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
269
297
  ### Notes
270
298
  - First release — exercising the automated npm OIDC publish pipeline end-to-end.
271
299
 
272
- [Unreleased]: https://github.com/Artui/ag-ui-web-component/compare/v0.5.0...HEAD
300
+ [Unreleased]: https://github.com/Artui/ag-ui-web-component/compare/v0.6.0...HEAD
301
+ [0.6.0]: https://github.com/Artui/ag-ui-web-component/compare/v0.5.0...v0.6.0
273
302
  [0.5.0]: https://github.com/Artui/ag-ui-web-component/compare/v0.4.0...v0.5.0
274
303
  [0.4.0]: https://github.com/Artui/ag-ui-web-component/compare/v0.3.1...v0.4.0
275
304
  [0.3.1]: https://github.com/Artui/ag-ui-web-component/compare/v0.3.0...v0.3.1
package/README.md CHANGED
@@ -152,6 +152,10 @@ That's the whole integration: an `endpoint` attribute pointing at your AG-UI ser
152
152
  | `data-skills` | — | Inline JSON skill catalog. |
153
153
  | `data-skills-url` | — | URL of a JSON skill catalog (fetched with `headers`). |
154
154
  | `data-tools-url` | — | URL of a server tool-label catalog (`[{ name, summary, description? }]`), fetched with `headers`; labels tool-call cards for server-side tools. |
155
+ | `data-threads-url` | — | URL of a server thread index (django-ag-ui's `ThreadsView`); enables durable, cross-device chat history. |
156
+ | `data-attachments-url` | — | URL of the file-upload endpoint (django-ag-ui's `AttachmentsView`); reveals the composer's 📎 picker + drag-and-drop. |
157
+ | `data-attachment-accept` | — | `<input accept>` list for client-side type filtering (e.g. `image/*,.pdf`). The server stays authoritative. |
158
+ | `data-attachment-max-bytes` | — | Client-side upload size cap in bytes (default 10 MiB; `0` disables). The server stays authoritative. |
155
159
  | `collapsed` | `collapsed` | Reflected boolean; collapses the widget. Persisted per-tab in `sessionStorage`. |
156
160
  | `theme` | — | CSS-only: `light` (default) / `dark` / `auto` / `code`. |
157
161
  | `density` | — | CSS-only: `comfortable` (default) / `compact`. |
@@ -159,8 +163,8 @@ That's the whole integration: an `endpoint` attribute pointing at your AG-UI ser
159
163
 
160
164
  **Properties** (JS only, not attributes): `headers`, `allowImages`, `autoConfirm`,
161
165
  `confirmPredicate`, `agentFactory`, `getTools`, `getContext`, `routeMap`, `navigate`,
162
- `getPageMap`, `autoInjectPageMap`, `conversationStore`, `navigationResult`, `skillContext`,
163
- `toolSummaries`, plus the mirrors `endpoint` / `toolDisplay` / `collapsed`.
166
+ `getPageMap`, `autoInjectPageMap`, `conversationStore`, `uploadHandler`, `navigationResult`,
167
+ `skillContext`, `toolSummaries`, plus the mirrors `endpoint` / `toolDisplay` / `collapsed`.
164
168
 
165
169
  `allowImages` (default `false`) re-enables `<img>` in rendered assistant markdown.
166
170
  It is off by default because a model-controlled image URL is fetched by the browser
@@ -525,6 +529,57 @@ chat.navigate = (path) => router.push(path); // SPA: in-page, no reload
525
529
 
526
530
  Route map + `navigate()` and the reload model are the same feature seen from two ends.
527
531
 
532
+ ## File uploads
533
+
534
+ Set **`data-attachments-url`** (django-ag-ui's `AttachmentsView`) to let the user attach files
535
+ to a message. A 📎 button and drag-and-drop appear on the composer; each picked file uploads
536
+ out-of-band (multipart, with the element's `headers`) and shows a chip in a pending tray —
537
+ `uploading` (with a progress bar) → `ready`, or `error` with a retry. On send, the ready files'
538
+ **refs** ride on the user bubble as read-only chips and the agent reads their contents
539
+ server-side via the `read_attachment` tool. The wire stays vanilla AG-UI: only lightweight refs
540
+ (`{ id, name, mime, size }`) travel, never the bytes.
541
+
542
+ ```html
543
+ <ag-ui-chat
544
+ endpoint="/agent/"
545
+ data-attachments-url="/agent/attachments/"
546
+ data-attachment-accept="image/*,application/pdf,text/plain"
547
+ data-attachment-max-bytes="10485760"
548
+ ></ag-ui-chat>
549
+ ```
550
+
551
+ Client-side `accept` / size checks are an instant-feedback nicety — **the server is
552
+ authoritative**. Refs persist on the message, so a restored conversation re-renders its chips.
553
+ Without the attribute the affordance stays hidden and the chat is text-only.
554
+
555
+ **Swapping the upload transport.** The built-in multipart `POST` is just the default
556
+ `uploadHandler`. Set your own to use a different transport — a resumable
557
+ [`tus-js-client`](https://github.com/tus/tus-js-client) adapter, direct-to-S3 multipart, etc.
558
+ — without touching the tray, the chips, or the AG-UI wire (refs are transport-agnostic). The
559
+ handler is `(file, onProgress) => Promise<AttachmentRef>`; when set, the 📎 affordance appears
560
+ even with no `data-attachments-url`, and your handler owns its own endpoint and headers:
561
+
562
+ ```js
563
+ import { Upload } from "tus-js-client";
564
+
565
+ chat.uploadHandler = (file, onProgress) =>
566
+ new Promise((resolve, reject) => {
567
+ const up = new Upload(file, {
568
+ endpoint: "/tus/",
569
+ headers: chat.headers,
570
+ onProgress: (sent, total) => onProgress(sent / total),
571
+ onError: reject,
572
+ onSuccess: () =>
573
+ resolve({ id: up.url.split("/").pop(), name: file.name, mime: file.type, size: file.size }),
574
+ });
575
+ up.start();
576
+ });
577
+ ```
578
+
579
+ The server side is the matching half: the agent reads bytes by ref id, so point the
580
+ `read_attachment` store at wherever your transport persisted them (django-ag-ui's
581
+ `AttachmentStore` is the seam). The refs themselves never change shape.
582
+
528
583
  ---
529
584
 
530
585
  ## Public API surface
@@ -580,9 +635,21 @@ re-export point. Internal modules import from leaf paths.
580
635
  | Export | Kind | Summary |
581
636
  | --- | --- | --- |
582
637
  | `SessionStorageStore` | class | Default per-tab conversation store. |
638
+ | `RemoteConversationStore` | class | Server-backed store over a `data-threads-url` endpoint. |
583
639
  | `ClientConversationStore` | type | The persistence seam. |
640
+ | `ThreadMeta` | type | A thread-drawer row (`{ threadId, title, updatedAt, preview }`). |
584
641
  | `NavigationCheckpoint` | type | The pre-reload checkpoint marker. |
585
642
 
643
+ ### Attachments
644
+
645
+ | Export | Kind | Summary |
646
+ | --- | --- | --- |
647
+ | `uploadAttachment(file, options)` | function | The built-in upload (multipart, progress) → `AttachmentRef`. |
648
+ | `UploadOptions` | type | `{ url, headers?, onProgress?, signal? }`. |
649
+ | `UploadHandler` | type | `(file, onProgress) => Promise<AttachmentRef>` — the `uploadHandler` swap seam (TUS / S3). |
650
+ | `AttachmentRef` | type | The durable upload ref (`{ id, name, mime, size, url? }`). |
651
+ | `messageAttachments(message)` | function | Read the refs a restored user message carries. |
652
+
586
653
  ### UI & DOM primitives
587
654
 
588
655
  | Export | Kind | Summary |