@artooi/ag-ui-web-component 0.2.2 → 0.3.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.
@@ -0,0 +1,19 @@
1
+ /**
2
+ * One entry in the server-tool catalog served by django-ag-ui's `tools/`
3
+ * endpoint and fetched via the `data-tools-url` attribute.
4
+ */
5
+ export interface ToolCatalogEntry {
6
+ /** The tool's wire name (matches the name in `TOOL_CALL_START`). */
7
+ readonly name: string;
8
+ /** A friendly card label for the tool. */
9
+ readonly summary: string;
10
+ /** Optional longer blurb (e.g. for a future tooltip). */
11
+ readonly description?: string;
12
+ }
13
+ /**
14
+ * Parse a fetched tool catalog into a `name → summary` map, skipping any entry
15
+ * that isn't a `{ name: string, summary: string }` object. Tolerant by design:
16
+ * a malformed payload yields an empty map rather than throwing.
17
+ */
18
+ export declare function parseToolCatalog(data: unknown): Record<string, string>;
19
+ //# sourceMappingURL=parse_tool_catalog.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"parse_tool_catalog.d.ts","sourceRoot":"","sources":["../../src/tools/parse_tool_catalog.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,MAAM,WAAW,gBAAgB;IAC/B,oEAAoE;IACpE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,0CAA0C;IAC1C,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,yDAAyD;IACzD,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;CAC/B;AAED;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,OAAO,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAiBtE"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@artooi/ag-ui-web-component",
3
- "version": "0.2.2",
3
+ "version": "0.3.0",
4
4
  "description": "Framework-free <ag-ui-chat> Web Component over the AG-UI protocol. Drop-in chat sidebar with a pluggable client-side tool registry, DOM driver primitives, animations, and destructive-action confirmation modal.",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -15,6 +15,7 @@ import { type ClientTool, ClientToolRegistry } from "../tools/client_tool_regist
15
15
  import { isDestructive } from "../tools/is_destructive.js";
16
16
  import { isNavigates } from "../tools/is_navigates.js";
17
17
  import { createPageMapContext, type PageMap } from "../tools/page_map.js";
18
+ import { parseToolCatalog } from "../tools/parse_tool_catalog.js";
18
19
  import { createRouteTools, type RouteMap } from "../tools/route_map.js";
19
20
  import { createStateHookTools, type StateHook } from "../tools/state_hook.js";
20
21
  import { type ConfirmationRequest, requestConfirmation } from "../ui/confirmation_card.js";
@@ -159,6 +160,13 @@ export class AgUiChat extends HTMLElement {
159
160
  */
160
161
  toolSummaries: Record<string, string> = {};
161
162
 
163
+ /**
164
+ * Card labels fetched from a server tool catalog (`data-tools-url`), keyed by
165
+ * tool name. The base layer behind {@link toolSummaries}: an explicit entry in
166
+ * `toolSummaries` wins, this fills the rest. Populated once on connect.
167
+ */
168
+ #toolCatalog: Record<string, string> = {};
169
+
162
170
  readonly #toolRegistry = new ClientToolRegistry();
163
171
  /** Tool-call cards awaiting execution, keyed by call id. */
164
172
  readonly #toolCards = new Map<string, ToolCallCard>();
@@ -312,10 +320,25 @@ export class AgUiChat extends HTMLElement {
312
320
  this.setAttribute("collapsed", "");
313
321
  }
314
322
  this.#initSkills();
323
+ void this.#fetchToolCatalog();
315
324
  this.#threadId = this.conversationStore.threadId();
316
325
  void this.#rehydrate();
317
326
  }
318
327
 
328
+ /** Fetch the server tool-label catalog from `data-tools-url`, if set. */
329
+ async #fetchToolCatalog(): Promise<void> {
330
+ const url = this.getAttribute("data-tools-url");
331
+ if (url === null) {
332
+ return;
333
+ }
334
+ try {
335
+ const response = await fetch(url, { headers: this.headers });
336
+ this.#toolCatalog = parseToolCatalog(await response.json());
337
+ } catch {
338
+ // Network/parse failure: cards fall back to toolSummaries / raw names.
339
+ }
340
+ }
341
+
319
342
  /**
320
343
  * Replace the host-supplied (client) skill catalog. Merged after the embedded
321
344
  * and fetched skills (so a client skill overrides a same-named server one).
@@ -871,10 +894,14 @@ export class AgUiChat extends HTMLElement {
871
894
  if (existing !== undefined) {
872
895
  return existing;
873
896
  }
874
- // Prefer the tool's own `x-summary`; fall back to the `toolSummaries` map
875
- // for server-side tools whose schema never reached the browser.
897
+ // Prefer the tool's own `x-summary`; then an explicit `toolSummaries`
898
+ // entry; then the fetched server catalog (`data-tools-url`). All cover
899
+ // server-side tools whose schema never reached the browser.
876
900
  const labelled = this.#resolveTool(call.name)?.parameters[X_SUMMARY_KEY];
877
- const summary = typeof labelled === "string" ? labelled : this.toolSummaries[call.name];
901
+ const summary =
902
+ typeof labelled === "string"
903
+ ? labelled
904
+ : (this.toolSummaries[call.name] ?? this.#toolCatalog[call.name]);
878
905
  const card = new ToolCallCard(call.name, call.args, this.toolDisplay, summary);
879
906
  this.#toolCards.set(call.id, card);
880
907
  this.#messages.appendChild(card.element);
package/src/index.ts CHANGED
@@ -71,6 +71,7 @@ export { type ClientTool, ClientToolRegistry } from "./tools/client_tool_registr
71
71
  export { isDestructive } from "./tools/is_destructive.js";
72
72
  export { isNavigates } from "./tools/is_navigates.js";
73
73
  export { createPageMapContext, type PageMap } from "./tools/page_map.js";
74
+ export { parseToolCatalog, type ToolCatalogEntry } from "./tools/parse_tool_catalog.js";
74
75
  export {
75
76
  createRouteTools,
76
77
  type Route,
@@ -0,0 +1,36 @@
1
+ /**
2
+ * One entry in the server-tool catalog served by django-ag-ui's `tools/`
3
+ * endpoint and fetched via the `data-tools-url` attribute.
4
+ */
5
+ export interface ToolCatalogEntry {
6
+ /** The tool's wire name (matches the name in `TOOL_CALL_START`). */
7
+ readonly name: string;
8
+ /** A friendly card label for the tool. */
9
+ readonly summary: string;
10
+ /** Optional longer blurb (e.g. for a future tooltip). */
11
+ readonly description?: string;
12
+ }
13
+
14
+ /**
15
+ * Parse a fetched tool catalog into a `name → summary` map, skipping any entry
16
+ * that isn't a `{ name: string, summary: string }` object. Tolerant by design:
17
+ * a malformed payload yields an empty map rather than throwing.
18
+ */
19
+ export function parseToolCatalog(data: unknown): Record<string, string> {
20
+ const out: Record<string, string> = {};
21
+ if (!Array.isArray(data)) {
22
+ return out;
23
+ }
24
+ for (const entry of data) {
25
+ if (entry === null || typeof entry !== "object") {
26
+ continue;
27
+ }
28
+ const record = entry as Record<string, unknown>;
29
+ const name = record["name"];
30
+ const summary = record["summary"];
31
+ if (typeof name === "string" && typeof summary === "string") {
32
+ out[name] = summary;
33
+ }
34
+ }
35
+ return out;
36
+ }
package/src/version.ts CHANGED
@@ -1 +1 @@
1
- export const VERSION: string = "0.2.2";
1
+ export const VERSION: string = "0.3.0";