@artooi/ag-ui-web-component 0.6.0 → 0.7.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.
Files changed (41) hide show
  1. package/CHANGELOG.md +44 -1
  2. package/README.md +140 -6
  3. package/dist/ag-ui-web-component.bundle.js +145 -47
  4. package/dist/ag-ui-web-component.bundle.js.map +4 -4
  5. package/dist/core/ag_ui_chat.d.ts +16 -0
  6. package/dist/core/ag_ui_chat.d.ts.map +1 -1
  7. package/dist/core/agui_client.d.ts +16 -0
  8. package/dist/core/agui_client.d.ts.map +1 -1
  9. package/dist/index.d.ts +3 -1
  10. package/dist/index.d.ts.map +1 -1
  11. package/dist/index.js +672 -228
  12. package/dist/index.js.map +3 -3
  13. package/dist/tools/page_action_tools.d.ts +31 -0
  14. package/dist/tools/page_action_tools.d.ts.map +1 -0
  15. package/dist/ui/attachment_tray.d.ts +3 -0
  16. package/dist/ui/attachment_tray.d.ts.map +1 -1
  17. package/dist/ui/confirmation_card.d.ts +4 -1
  18. package/dist/ui/confirmation_card.d.ts.map +1 -1
  19. package/dist/ui/relative_time.d.ts +5 -3
  20. package/dist/ui/relative_time.d.ts.map +1 -1
  21. package/dist/ui/styles.d.ts +1 -1
  22. package/dist/ui/styles.d.ts.map +1 -1
  23. package/dist/ui/thread_drawer.d.ts +7 -1
  24. package/dist/ui/thread_drawer.d.ts.map +1 -1
  25. package/dist/ui/tool_call_card.d.ts +6 -2
  26. package/dist/ui/tool_call_card.d.ts.map +1 -1
  27. package/dist/ui/ui_strings.d.ts +126 -0
  28. package/dist/ui/ui_strings.d.ts.map +1 -0
  29. package/package.json +1 -1
  30. package/src/core/ag_ui_chat.ts +213 -41
  31. package/src/core/agui_client.ts +33 -2
  32. package/src/index.ts +7 -0
  33. package/src/tools/page_action_tools.ts +130 -0
  34. package/src/ui/attachment_tray.ts +13 -7
  35. package/src/ui/confirmation_card.ts +15 -5
  36. package/src/ui/relative_time.ts +15 -8
  37. package/src/ui/styles.ts +98 -0
  38. package/src/ui/thread_drawer.ts +53 -25
  39. package/src/ui/tool_call_card.ts +40 -17
  40. package/src/ui/ui_strings.ts +208 -0
  41. package/src/version.ts +1 -1
package/CHANGELOG.md CHANGED
@@ -7,6 +7,48 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
7
7
 
8
8
  ## [Unreleased]
9
9
 
10
+ ## [0.7.0] — 2026-06-26
11
+
12
+ ### Added
13
+
14
+ - **Localization (i18n).** Every user-facing string — labels, placeholders,
15
+ `aria-label`s, and `title` tooltips — now reads from a flat `UiStrings` table.
16
+ Override any subset via the `strings` property or the `data-strings` JSON
17
+ attribute (the property wins key-by-key); the rest fall back to the English
18
+ defaults. A few keys are `{token}` templates (`minutesAgo`, `confirmRun`,
19
+ `tooLarge`, …). New exports: `UiStrings`, `DEFAULT_UI_STRINGS`,
20
+ `mergeUiStrings`.
21
+ - **`::part()` styling and replaceable slots.** Every structural element exposes
22
+ a stable `part` (`panel`, `header`, `title`, `messages`, `tool-card`,
23
+ `composer`, `input`, `send`, `launcher`, the drawer parts, …) so hosts restyle
24
+ from outside the Shadow DOM without piercing it. Coarse slots — `icon`,
25
+ `header-actions`, `empty`, `footer`, `launcher` — replace whole regions with
26
+ host markup.
27
+ - **Header / launcher icon.** An `icon` slot (any markup) before the title, or
28
+ the `data-icon-url` attribute convenience (an `<img>`); the slot wins. Sized
29
+ via `--ag-ui-icon-size`.
30
+ - **Sidebar placement.** `placement="sidebar"` is a full-height docked panel
31
+ that slides open/closed and collapses to a slim icon **rail** (instead of the
32
+ floating launcher). Docks right by default; `data-side="left"` docks left.
33
+ Overlays by default (`--ag-ui-position: static` for host-managed push); the
34
+ slide honours `prefers-reduced-motion`; the rail carries `aria-expanded`.
35
+ - **Built-in page-action tools.** Opt in via `data-page-actions` (a comma list of
36
+ `scroll` / `drag`): `scroll_to` (a target into view — `top` / `bottom` / a
37
+ selector or page-map id) and `drag_and_drop` (fires the native HTML5 drag
38
+ sequence so the page's own drop handler reacts). Targets resolve through the
39
+ overridable `resolvePageTarget` property. Not stamped destructive — gate
40
+ auto-persist-on-drop pages with `confirmPredicate`. New exports:
41
+ `createPageActionTools`, `PAGE_ACTIONS`, `ResolvePageTarget`.
42
+
43
+ ### Fixed
44
+
45
+ - **Stuck "pending" UI when the stream drops mid-run.** A run whose stream closes
46
+ without a terminal `RUN_FINISHED` / `RUN_ERROR` event used to resolve as if it
47
+ had succeeded, leaving the thinking indicator — and any in-flight tool card —
48
+ stuck forever. Such a close is now surfaced as a connection-loss error (the
49
+ localizable `connectionLost` string), and `onSettled` sweeps any tool card
50
+ still pending to the no-result fallback. New export: `ConnectionLostError`.
51
+
10
52
  ## [0.6.0] — 2026-06-25
11
53
 
12
54
  ### Added
@@ -297,7 +339,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
297
339
  ### Notes
298
340
  - First release — exercising the automated npm OIDC publish pipeline end-to-end.
299
341
 
300
- [Unreleased]: https://github.com/Artui/ag-ui-web-component/compare/v0.6.0...HEAD
342
+ [Unreleased]: https://github.com/Artui/ag-ui-web-component/compare/v0.7.0...HEAD
343
+ [0.7.0]: https://github.com/Artui/ag-ui-web-component/compare/v0.6.0...v0.7.0
301
344
  [0.6.0]: https://github.com/Artui/ag-ui-web-component/compare/v0.5.0...v0.6.0
302
345
  [0.5.0]: https://github.com/Artui/ag-ui-web-component/compare/v0.4.0...v0.5.0
303
346
  [0.4.0]: https://github.com/Artui/ag-ui-web-component/compare/v0.3.1...v0.4.0
package/README.md CHANGED
@@ -44,6 +44,7 @@ No framework, no Django, no admin specifics live here. Downstream consumers (e.g
44
44
  - [Registering tools](#registering-tools)
45
45
  - [Inline confirmation (`x-destructive` / `x-confirm` / `confirmPredicate`)](#inline-confirmation-x-destructive--x-confirm--confirmpredicate)
46
46
  - [DOM-driver and animation primitives](#dom-driver-and-animation-primitives)
47
+ - [Page-action tools](#page-action-tools)
47
48
  - [New chat and collapse](#new-chat-and-collapse)
48
49
  - [Tool-call display modes](#tool-call-display-modes)
49
50
  - [Markdown rendering](#markdown-rendering)
@@ -52,6 +53,7 @@ No framework, no Django, no admin specifics live here. Downstream consumers (e.g
52
53
  - [Host seams: the SPA story](#host-seams-the-spa-story)
53
54
  - [Public API surface](#public-api-surface)
54
55
  - [Theming, density, and placement](#theming-density-and-placement)
56
+ - [Internationalization (i18n)](#internationalization-i18n)
55
57
  - [Building the bundle](#building-the-bundle)
56
58
  - [Compatibility](#compatibility)
57
59
 
@@ -156,15 +158,20 @@ That's the whole integration: an `endpoint` attribute pointing at your AG-UI ser
156
158
  | `data-attachments-url` | — | URL of the file-upload endpoint (django-ag-ui's `AttachmentsView`); reveals the composer's 📎 picker + drag-and-drop. |
157
159
  | `data-attachment-accept` | — | `<input accept>` list for client-side type filtering (e.g. `image/*,.pdf`). The server stays authoritative. |
158
160
  | `data-attachment-max-bytes` | — | Client-side upload size cap in bytes (default 10 MiB; `0` disables). The server stays authoritative. |
159
- | `collapsed` | `collapsed` | Reflected boolean; collapses the widget. Persisted per-tab in `sessionStorage`. |
161
+ | `data-strings` | `strings` | Partial JSON override of the UI string table (localization). The property wins key-by-key over the attribute; see [Internationalization](#internationalization-i18n). |
162
+ | `data-icon-url` | — | Header (and sidebar-rail) icon image URL. A slotted `slot="icon"` wins; see [Header & launcher icon](#header-and-launcher-icon). |
163
+ | `data-page-actions` | — | Opt-in built-in page-action tools: a comma list of `scroll` / `drag` (e.g. `"scroll,drag"`). See [Page-action tools](#page-action-tools). |
164
+ | `data-side` | — | CSS-only, for `placement="sidebar"`: which edge it docks to — `right` (default) / `left`. |
165
+ | `collapsed` | `collapsed` | Reflected boolean; collapses the widget (to a rail under `placement="sidebar"`). Persisted per-tab in `sessionStorage`. |
160
166
  | `theme` | — | CSS-only: `light` (default) / `dark` / `auto` / `code`. |
161
167
  | `density` | — | CSS-only: `comfortable` (default) / `compact`. |
162
- | `placement` | — | CSS-only: `floating` (default) / `bottom-left` / `side` / `full` / `embedded`. |
168
+ | `placement` | — | CSS-only: `floating` (default) / `bottom-left` / `side` / `sidebar` / `full` / `embedded`. |
163
169
 
164
170
  **Properties** (JS only, not attributes): `headers`, `allowImages`, `autoConfirm`,
165
171
  `confirmPredicate`, `agentFactory`, `getTools`, `getContext`, `routeMap`, `navigate`,
166
172
  `getPageMap`, `autoInjectPageMap`, `conversationStore`, `uploadHandler`, `navigationResult`,
167
- `skillContext`, `toolSummaries`, plus the mirrors `endpoint` / `toolDisplay` / `collapsed`.
173
+ `skillContext`, `toolSummaries`, `strings`, `resolvePageTarget`, plus the mirrors
174
+ `endpoint` / `toolDisplay` / `collapsed`.
168
175
 
169
176
  `allowImages` (default `false`) re-enables `<img>` in rendered assistant markdown.
170
177
  It is off by default because a model-controlled image URL is fetched by the browser
@@ -329,6 +336,36 @@ register the change.
329
336
  Each takes an element the caller has already located; host packages wrap them with
330
337
  environment-aware lookups (e.g. "find `#id_<name>`, then `fillField`").
331
338
 
339
+ ### Page-action tools
340
+
341
+ Two built-in client tools let the agent perform common page interactions without every host
342
+ re-implementing them. They are **opt-in** via `data-page-actions` — a comma list of the tokens you
343
+ want — so you control the agent's interaction surface:
344
+
345
+ ```html
346
+ <ag-ui-chat endpoint="/agent/" data-page-actions="scroll,drag"></ag-ui-chat>
347
+ ```
348
+
349
+ - **`scroll_to`** — scroll a target into view. `target` is `"top"`, `"bottom"`, or a CSS selector
350
+ / page-map element id. Read-only (no confirmation).
351
+ - **`drag_and_drop`** — drag the `from` element onto the `to` element (selectors / page-map ids),
352
+ firing the standard HTML5 drag sequence (`dragstart` → `dragenter`/`dragover`/`drop` → `dragend`)
353
+ so the page's own drop handler reacts. Useful for reordering sortable lists.
354
+
355
+ Targets resolve through the overridable `resolvePageTarget` property — `(target) => HTMLElement |
356
+ null`, defaulting to `document.querySelector`. A host with a page map overrides it to map its own
357
+ element ids (the same way the DOM-driver primitives are wrapped with environment-aware lookups):
358
+
359
+ ```js
360
+ chat.resolvePageTarget = (id) => myPageMap.elementFor(id);
361
+ ```
362
+
363
+ **Destructiveness.** Page actions are *not* stamped `x-destructive` — a drag rearranges transient
364
+ state, and the durable change happens at the page's explicit commit (a Save), which stays in the
365
+ user's hands. If your page persists *on drop* (a kanban board firing a PATCH from the drop
366
+ handler), gate `drag_and_drop` with [`confirmPredicate`](#inline-confirmation-x-destructive--x-confirm--confirmpredicate)
367
+ — or don't enable it. A target that resolves to nothing returns a clean, model-readable tool error.
368
+
332
369
  ---
333
370
 
334
371
  ## New chat and collapse
@@ -604,6 +641,7 @@ re-export point. Internal modules import from leaf paths.
604
641
  | `AgUiClient` | class | Orchestration layer over an AG-UI `AbstractAgent`. |
605
642
  | `AgUiClientConfig` / `AgUiClientHandlers` / `AgUiRunInputs` | type | Client config, lifecycle handlers, per-run input providers. |
606
643
  | `AgUiToolCall` / `ToolExecution` / `ExecuteTool` | type | Tool-call shape, execution result, executor signature. |
644
+ | `ConnectionLostError` | class | Raised (→ `onError`) when a run's stream closes with no terminal AG-UI event. |
607
645
  | `createHttpAgent(options)` | function | Default agent factory (wraps `HttpAgent`). |
608
646
  | `AgentFactory` / `HttpAgentOptions` | type | Factory signature and its options. |
609
647
 
@@ -615,6 +653,9 @@ re-export point. Internal modules import from leaf paths.
615
653
  | `ClientTool` | type | A frontend tool declaration. |
616
654
  | `isDestructive(parameters)` | function | Read the `x-destructive` flag. |
617
655
  | `isNavigates(parameters)` | function | Read the `x-navigates` flag. |
656
+ | `createPageActionTools(enabled, resolveTarget)` | function | Build the opt-in `scroll_to` / `drag_and_drop` tools. |
657
+ | `PAGE_ACTIONS` | const | The page-action opt-in tokens (`scroll` / `drag`). |
658
+ | `ResolvePageTarget` | type | `(target) => HTMLElement | null` — the page-target resolver. |
618
659
  | `X_DESTRUCTIVE_KEY` / `X_NAVIGATES_KEY` | const | The JSON-Schema extension keys. |
619
660
 
620
661
  ### Host seams
@@ -658,7 +699,10 @@ re-export point. Internal modules import from leaf paths.
658
699
  | `ToolCallStatus` / `SettledStatus` / `ToolDisplayMode` | type | Card lifecycle states + display mode. |
659
700
  | `requestConfirmation(host, request, options?)` | function | Append the inline confirmation card to the transcript. |
660
701
  | `ConfirmationRequest` | type | What the card displays. |
661
- | `ConfirmationOptions` | type | `{ signal? }` — aborting resolves the card as declined (the Stop control's hook). |
702
+ | `ConfirmationOptions` | type | `{ signal?, strings? }` — abort resolves the card as declined; `strings` localizes it. |
703
+ | `UiStrings` | type | The flat table of every user-facing string. |
704
+ | `DEFAULT_UI_STRINGS` | const | The English defaults (the override floor). |
705
+ | `mergeUiStrings(overrides)` | function | Merge a partial override over the defaults. |
662
706
  | `renderMarkdown(text)` | function | Render sanitized markdown/HTML (marked + DOMPurify). |
663
707
  | `typeInto` / `highlightThenClick` / `pressThenClick` / `selectOption` / `toggleControl` / `scrollIntoCenterView` / `focusWithFlash` / `prefersReducedMotion` | function | Animation primitives. |
664
708
  | `fillField` / `clickElement` / `pressButton` / `selectControl` / `setControlValue` / `toggleCheckbox` | function | DOM-driver primitives. |
@@ -708,8 +752,8 @@ have to hand-tune the variables:
708
752
 
709
753
  - `theme` — `light` (default) / `dark` / `auto` (follow the OS) / `code`.
710
754
  - `density` — `comfortable` (default) / `compact`.
711
- - `placement` — `floating` (default) / `bottom-left` / `side` / `full` / `embedded`. `embedded`
712
- drops the fixed positioning and z-index so the widget sits in normal document flow.
755
+ - `placement` — `floating` (default) / `bottom-left` / `side` / `sidebar` / `full` / `embedded`.
756
+ `embedded` drops the fixed positioning and z-index so the widget sits in normal document flow.
713
757
 
714
758
  ```html
715
759
  <ag-ui-chat endpoint="/agent/" theme="dark" density="compact" placement="side"></ag-ui-chat>
@@ -719,6 +763,96 @@ See [`src/ui/styles.ts`](src/ui/styles.ts) for the full variable + preset list.
719
763
  [`demo/`](demo/) live playground (`node demo/mock-server.mjs`) flips theme, density, placement,
720
764
  text-animation, and tool-display live from a single page.
721
765
 
766
+ ### Parts and slots
767
+
768
+ For styling beyond the `--ag-ui-*` variables, every structural element exposes a `part` so you can
769
+ reach it from outside the Shadow DOM with `::part()` — no shadow piercing. The part names are
770
+ **public API** (additions are non-breaking; renames are breaking):
771
+
772
+ ```css
773
+ ag-ui-chat::part(panel) { border-radius: 0; }
774
+ ag-ui-chat::part(header) { background: #111; }
775
+ ag-ui-chat::part(send) { text-transform: uppercase; }
776
+ ag-ui-chat::part(tool-card) { font-family: var(--my-mono); }
777
+ ```
778
+
779
+ Available parts: `panel`, `header`, `title`, `icon`, `header-controls`, `header-button`
780
+ (plus `history-button` / `new-button` / `collapse-button`), `messages`, `message` (plus
781
+ `message-user` / `message-assistant`), `empty`, `pending`, `tool-card` (plus `tool-card-head` /
782
+ `-name` / `-status` / `-args` / `-toggle` / `-result`), `confirm` (plus `confirm-body` /
783
+ `-args` / `-actions` / `-button` / `-cancel` / `-confirm`), `composer`, `input`, `send`,
784
+ `attach-button`, `attachment-tray`, `launcher`, `launcher-icon`, and the drawer parts
785
+ (`drawer`, `drawer-backdrop`, `drawer-panel`, `drawer-header`, `drawer-title`, `drawer-new`,
786
+ `drawer-list`, `drawer-empty`, `drawer-row`, `drawer-row-select`).
787
+
788
+ Coarse **slots** let you replace whole regions with your own markup (project light-DOM children
789
+ with a matching `slot=`):
790
+
791
+ | Slot | Where |
792
+ | --- | --- |
793
+ | `icon` | A header brand icon, before the title. |
794
+ | `header-actions` | Extra controls between the title and the built-in buttons. |
795
+ | `empty` | The empty-state shown before any message. |
796
+ | `footer` | Below the composer. |
797
+ | `launcher` | The collapsed sidebar rail's content. |
798
+
799
+ ```html
800
+ <ag-ui-chat endpoint="/agent/">
801
+ <img slot="icon" src="/logo.svg" alt="" />
802
+ <button slot="header-actions" onclick="openHelp()">?</button>
803
+ </ag-ui-chat>
804
+ ```
805
+
806
+ ### Header and launcher icon
807
+
808
+ Give the header a brand icon with either the `icon` slot (any markup) or the `data-icon-url`
809
+ convenience attribute (an `<img>`); the slot wins when both are set, and with neither the header
810
+ stays icon-less. The same icon seam feeds the collapsed sidebar rail. Size it via
811
+ `--ag-ui-icon-size` (default `22px`).
812
+
813
+ ```html
814
+ <ag-ui-chat endpoint="/agent/" data-icon-url="/logo.png"></ag-ui-chat>
815
+ ```
816
+
817
+ ### Sidebar placement
818
+
819
+ `placement="sidebar"` is a full-height **docked** panel that slides open/closed and collapses to a
820
+ slim **icon rail** (rather than the floating launcher). It docks right by default; `data-side="left"`
821
+ docks it left. Collapse state reuses the `collapsed` attribute (persisted per-tab), and the rail
822
+ carries `aria-expanded`. The slide honours `prefers-reduced-motion`.
823
+
824
+ ```html
825
+ <ag-ui-chat endpoint="/agent/" placement="sidebar" data-side="left"></ag-ui-chat>
826
+ ```
827
+
828
+ It overlays the page by default (no host-layout coupling). To make the host content reflow around
829
+ it instead, set `--ag-ui-position: static` and place the element in your own grid/flex layout.
830
+
831
+ ---
832
+
833
+ ## Internationalization (i18n)
834
+
835
+ Every user-facing string — labels, placeholders, `aria-label`s, and `title` tooltips — is read
836
+ from a flat `UiStrings` table, so a non-English host can translate the widget without forking it.
837
+ Override any subset; the rest fall back to the English defaults. Two equivalent seams:
838
+
839
+ ```js
840
+ // As a property (merged over the defaults):
841
+ chat.strings = { send: "Senden", inputPlaceholder: "Frag mich…", stop: "Stopp" };
842
+ ```
843
+
844
+ ```html
845
+ <!-- Or inline, as JSON (the property wins key-by-key when both are set): -->
846
+ <ag-ui-chat endpoint="/agent/" data-strings='{"send": "Senden", "inputPlaceholder": "Frag mich…"}'></ag-ui-chat>
847
+ ```
848
+
849
+ Set `strings` / `data-strings` **before** the element connects (they resolve on mount). A few keys
850
+ are templates carrying `{token}` placeholders the widget fills in — e.g. `minutesAgo`
851
+ (`"{n}m ago"`), `confirmRun` (`"Run “{tool}”?"`), `tooLarge` (`"Too large (max {size})"`). Keep the
852
+ token verbatim when translating. The full key list and English defaults live in
853
+ [`src/ui/ui_strings.ts`](src/ui/ui_strings.ts) (exported as `DEFAULT_UI_STRINGS`); `mergeUiStrings`
854
+ is exported too if you want to compute a complete table yourself.
855
+
722
856
  ---
723
857
 
724
858
  ## Building the bundle