@artooi/ag-ui-web-component 0.43.0 → 0.44.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.
@@ -1 +1 @@
1
- {"version":3,"file":"conversation_history.d.ts","sourceRoot":"","sources":["../../../src/ui/history/conversation_history.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"conversation_history.d.ts","sourceRoot":"","sources":["../../../src/ui/history/conversation_history.ts"],"names":[],"mappings":"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"}
@@ -1,3 +1,4 @@
1
+ import type { AgUiMessageIds } from "../../core/agui_client.js";
1
2
  import type { UiStrings } from "../ui_strings.js";
2
3
  /** What the answer actions need from the element that owns them. */
3
4
  export interface AnswerActionsHost {
@@ -7,6 +8,12 @@ export interface AnswerActionsHost {
7
8
  readonly strings: () => UiStrings;
8
9
  /** Retry the last turn, as the element's public `retryLastTurn` does. */
9
10
  readonly retry: () => void;
11
+ /** The element's current conversation thread. */
12
+ readonly threadId: () => string;
13
+ }
14
+ /** A finished bubble that is not an answer, and so carries no rating. */
15
+ interface Unrateable {
16
+ readonly rateable: false;
10
17
  }
11
18
  /**
12
19
  * The action row under a finished answer -- copy, retry, feedback -- and the
@@ -31,9 +38,11 @@ export declare class AnswerActions {
31
38
  * something survives to go in it: an empty row still takes its margin, still
32
39
  * answers to the `message-actions` part, and still reads to a screen reader
33
40
  * as a group of actions with none in it.
41
+ *
42
+ * `message` names the answer, which is what a rating is filed under; a bubble
43
+ * that is not an answer says so instead, and has no id to give.
34
44
  */
35
- attach(bubble: HTMLDivElement, options?: {
36
- rateable?: boolean;
37
- }): void;
45
+ attach(bubble: HTMLDivElement, message: AgUiMessageIds | Unrateable): void;
38
46
  }
47
+ export {};
39
48
  //# sourceMappingURL=answer_actions.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"answer_actions.d.ts","sourceRoot":"","sources":["../../../src/ui/transcript/answer_actions.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAGlD,oEAAoE;AACpE,MAAM,WAAW,iBAAiB;IAChC,wFAAwF;IACxF,QAAQ,CAAC,OAAO,EAAE,WAAW,CAAC;IAC9B,iCAAiC;IACjC,QAAQ,CAAC,OAAO,EAAE,MAAM,SAAS,CAAC;IAClC,yEAAyE;IACzE,QAAQ,CAAC,KAAK,EAAE,MAAM,IAAI,CAAC;CAC5B;AAED;;;;;;GAMG;AACH,qBAAa,aAAa;;IAaxB,YAAY,IAAI,EAAE,iBAAiB,EAElC;IAED,mEAAmE;IACnE,MAAM,IAAI,IAAI,CAEb;IAED;;;;;;;;;;;OAWG;IACH,MAAM,CAAC,MAAM,EAAE,cAAc,EAAE,OAAO,GAAE;QAAE,QAAQ,CAAC,EAAE,OAAO,CAAA;KAAO,GAAG,IAAI,CAwCzE;CAwCF"}
1
+ {"version":3,"file":"answer_actions.d.ts","sourceRoot":"","sources":["../../../src/ui/transcript/answer_actions.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAIhE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAGlD,oEAAoE;AACpE,MAAM,WAAW,iBAAiB;IAChC,wFAAwF;IACxF,QAAQ,CAAC,OAAO,EAAE,WAAW,CAAC;IAC9B,iCAAiC;IACjC,QAAQ,CAAC,OAAO,EAAE,MAAM,SAAS,CAAC;IAClC,yEAAyE;IACzE,QAAQ,CAAC,KAAK,EAAE,MAAM,IAAI,CAAC;IAC3B,iDAAiD;IACjD,QAAQ,CAAC,QAAQ,EAAE,MAAM,MAAM,CAAC;CACjC;AAED,yEAAyE;AACzE,UAAU,UAAU;IAClB,QAAQ,CAAC,QAAQ,EAAE,KAAK,CAAC;CAC1B;AAED;;;;;;GAMG;AACH,qBAAa,aAAa;;IAaxB,YAAY,IAAI,EAAE,iBAAiB,EAElC;IAED,mEAAmE;IACnE,MAAM,IAAI,IAAI,CAEb;IAED;;;;;;;;;;;;;;OAcG;IACH,MAAM,CAAC,MAAM,EAAE,cAAc,EAAE,OAAO,EAAE,cAAc,GAAG,UAAU,GAAG,IAAI,CAyDzE;CAwCF"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@artooi/ag-ui-web-component",
3
- "version": "0.43.0",
3
+ "version": "0.44.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",
package/src/constants.ts CHANGED
@@ -102,10 +102,18 @@ export const INVALIDATE_EVENT = "ag-ui-invalidate";
102
102
  /**
103
103
  * Fired when the user rates an assistant message from its action row.
104
104
  *
105
- * `detail` is a {@link FeedbackDetail}: the rated message's text and the
106
- * rating. **Nothing is stored** -- a rating belongs to whatever the host
107
- * already uses to hold product signals, and a write-only table inside a chat
108
- * widget is a schema nobody reads.
105
+ * `detail` is a {@link FeedbackDetail}: which message was rated -- its AG-UI
106
+ * `messageId` and the `threadId` it belongs to, plus the `runId` that streamed
107
+ * it when it arrived live (absent on a restored message, which carries no run
108
+ * id) -- with its text and the rating. A host stores the rating against
109
+ * `messageId`, not `content`: two answers can read the same. A restored
110
+ * message is named by the id its store returns, so with a server-backed store
111
+ * the id holds across a reload only where the server persists the ids it
112
+ * streamed; the built-in browser store keeps them as they streamed.
113
+ *
114
+ * **Nothing is stored** -- a rating belongs to whatever the host already uses
115
+ * to hold product signals, and a write-only table inside a chat widget is a
116
+ * schema nobody reads.
109
117
  */
110
118
  export const FEEDBACK_EVENT = "ag-ui-feedback";
111
119
 
@@ -445,6 +445,8 @@ export class AgUiChat extends HTMLElement {
445
445
  retry: () => {
446
446
  void this.retryLastTurn();
447
447
  },
448
+ // Late-bound: the history is built in the constructor, after this field.
449
+ threadId: () => this.#history.threadId,
448
450
  });
449
451
 
450
452
  readonly #root: ShadowRoot;
@@ -25,6 +25,29 @@ export interface AgUiToolCall {
25
25
  readonly args: Record<string, unknown>;
26
26
  }
27
27
 
28
+ /**
29
+ * Which message an answer surfaced by {@link AgUiClient} is, as the stream
30
+ * named it.
31
+ */
32
+ export interface AgUiMessageIds {
33
+ /** The id the message streamed under, on its `TEXT_MESSAGE_START`/`END`. */
34
+ readonly messageId: string;
35
+ /**
36
+ * The run that streamed it, as that run's `RUN_STARTED` declared it.
37
+ *
38
+ * Absent when no `RUN_STARTED` was seen. `@ag-ui/client` 1.0 rejects a
39
+ * stream whose first event is anything else, so over a real agent this is
40
+ * always present; nothing else names the run the server recorded, so
41
+ * nothing is substituted when it is not.
42
+ *
43
+ * Text a sub-agent streams through the parent run carries the parent's run
44
+ * id: that is the stream it arrived on, and the delegation's
45
+ * `subagentRunId` names the child's work rather than a run the answer is
46
+ * recorded under.
47
+ */
48
+ readonly runId?: string;
49
+ }
50
+
28
51
  /** The result of executing a frontend tool, destined for a tool-result message. */
29
52
  export interface ToolExecution {
30
53
  /** String content for the AG-UI tool-result message. */
@@ -92,8 +115,11 @@ export interface AgUiClientHandlers {
92
115
  onRunStart(): void;
93
116
  /** Fired on every streamed token; `buffer` is the full text so far. */
94
117
  onTextDelta(buffer: string): void;
95
- /** Fired when the assistant message completes; `buffer` is the final text. */
96
- onTextEnd(buffer: string): void;
118
+ /**
119
+ * Fired when the assistant message completes; `buffer` is the final text,
120
+ * and `message` names it as the stream did.
121
+ */
122
+ onTextEnd(buffer: string, message: AgUiMessageIds): void;
97
123
  /** Fired when the agent finishes calling a tool (server- or frontend-side). */
98
124
  onToolCall(call: AgUiToolCall): void;
99
125
  /**
@@ -786,10 +812,21 @@ export class AgUiClient {
786
812
  // Charts whose patch has been dispatched but not yet applied. Scoped to the
787
813
  // subscriber, so it cannot outlive the run that created it.
788
814
  const pendingDeltas = new Set<string>();
815
+ // The run this round's stream declared. Per subscriber, so per round: a
816
+ // turn that calls a tool is two runs, and its answer belongs to the second.
817
+ //
818
+ // Taken from `RUN_STARTED` rather than the `runId` the request carried.
819
+ // The client mints that one, and a server is free to record the run under
820
+ // the id it streams back; the event is the server's own statement of
821
+ // which run this is, so it is the id a host can find again.
822
+ let runId: string | undefined;
789
823
  return {
790
824
  onRunInitialized() {
791
825
  h.onRunStart();
792
826
  },
827
+ onRunStartedEvent({ event }) {
828
+ runId = event.runId;
829
+ },
793
830
  onTextMessageStartEvent({ event }) {
794
831
  // A reused message id merges two answers into one persisted transcript
795
832
  // entry. The protocol has no rule to enforce and refusing the event
@@ -809,7 +846,10 @@ export class AgUiClient {
809
846
  },
810
847
  onTextMessageEndEvent({ event, textMessageBuffer }) {
811
848
  closed.add(event.messageId);
812
- h.onTextEnd(textMessageBuffer);
849
+ h.onTextEnd(textMessageBuffer, {
850
+ messageId: event.messageId,
851
+ ...(runId === undefined ? {} : { runId }),
852
+ });
813
853
  },
814
854
  onToolCallEndEvent({ event, toolCallName, toolCallArgs }) {
815
855
  const call: AgUiToolCall = {
@@ -3,4 +3,25 @@ export interface FeedbackDetail {
3
3
  /** The rated message's text, as rendered. */
4
4
  readonly content: string;
5
5
  readonly rating: "up" | "down";
6
+ /**
7
+ * The AG-UI id of the rated assistant message: the id it streamed under, or
8
+ * the stored message's `id` when it was restored from history.
9
+ *
10
+ * What a host stores a rating against. `content` cannot be: two answers can
11
+ * read the same, and the text says nothing about which stored message it
12
+ * was. A restored message carries whatever id its store returns: the
13
+ * built-in browser store keeps the streamed ids, and a server-backed one
14
+ * keeps them only where the server persists the ids it streamed.
15
+ */
16
+ readonly messageId: string;
17
+ /** The conversation the message belongs to: the element's thread when it was drawn. */
18
+ readonly threadId: string;
19
+ /**
20
+ * The run that streamed the message, as its `RUN_STARTED` named it.
21
+ *
22
+ * Present only on a message that arrived live. A restored one has none to
23
+ * give -- an AG-UI message carries no run id -- so the key is absent there
24
+ * rather than holding a value that only looks like one.
25
+ */
26
+ readonly runId?: string;
6
27
  }
@@ -235,7 +235,7 @@ export class RunHandlers {
235
235
  this.#host.stream.queue(buffer);
236
236
  this.#host.stream.countDelta();
237
237
  },
238
- onTextEnd: (buffer) => {
238
+ onTextEnd: (buffer, message) => {
239
239
  // A text message that carried no content is a declaration, not an
240
240
  // answer, and drawing one puts an empty bubble above every tool call.
241
241
  //
@@ -265,7 +265,7 @@ export class RunHandlers {
265
265
  this.#host.transcript.revealWords(bubble);
266
266
  }
267
267
  attachCopyButtons(bubble, this.#host.strings());
268
- this.#host.actions.attach(bubble);
268
+ this.#host.actions.attach(bubble, message);
269
269
  this.#host.stream.end();
270
270
  this.#host.noteUnread();
271
271
  },
package/src/index.ts CHANGED
@@ -34,6 +34,7 @@ export {
34
34
  AgUiClient,
35
35
  type AgUiClientConfig,
36
36
  type AgUiClientHandlers,
37
+ type AgUiMessageIds,
37
38
  type AgUiRunInputs,
38
39
  type AgUiToolCall,
39
40
  ConnectionLostError,
@@ -916,7 +916,20 @@ export class ConversationHistory {
916
916
  // wrap words.
917
917
  const restoredBubble = this.#host.appendMessage(MESSAGE_ROLE.ASSISTANT, text);
918
918
  restoredBubble.classList.add("message--restored");
919
- this.#host.actions.attach(restoredBubble);
919
+ // The stored id, which is the streamed one wherever the store kept
920
+ // it. A Retry re-renders the turns it keeps through here too, so a
921
+ // kept answer stays the message it was. No run id: a stored message
922
+ // does not carry one.
923
+ //
924
+ // Narrowed rather than trusted, like the fields below: a host store or
925
+ // a `data-threads-url` server can return a message with no id, and a
926
+ // rating that names nothing is a pair of buttons that lead nowhere.
927
+ // Such an answer keeps its copy and loses only the rating.
928
+ const id: unknown = message.id;
929
+ this.#host.actions.attach(
930
+ restoredBubble,
931
+ typeof id === "string" && id !== "" ? { messageId: id } : { rateable: false },
932
+ );
920
933
  }
921
934
  // Narrowed rather than trusted, for the same reason `messageAttachments`
922
935
  // narrows the neighbouring field: anything that throws in this loop aborts
@@ -1,4 +1,5 @@
1
1
  import { FEEDBACK_EVENT, ICON_RETRY, MESSAGE_ACTIONS } from "../../constants.js";
2
+ import type { AgUiMessageIds } from "../../core/agui_client.js";
2
3
  import type { FeedbackDetail } from "../../core/events/feedback_detail.js";
3
4
  import { commaTokens } from "../../core/utils.js";
4
5
  import { copyPayload } from "../excerpts/copy_payload.js";
@@ -13,6 +14,13 @@ export interface AnswerActionsHost {
13
14
  readonly strings: () => UiStrings;
14
15
  /** Retry the last turn, as the element's public `retryLastTurn` does. */
15
16
  readonly retry: () => void;
17
+ /** The element's current conversation thread. */
18
+ readonly threadId: () => string;
19
+ }
20
+
21
+ /** A finished bubble that is not an answer, and so carries no rating. */
22
+ interface Unrateable {
23
+ readonly rateable: false;
16
24
  }
17
25
 
18
26
  /**
@@ -55,15 +63,26 @@ export class AnswerActions {
55
63
  * something survives to go in it: an empty row still takes its margin, still
56
64
  * answers to the `message-actions` part, and still reads to a screen reader
57
65
  * as a group of actions with none in it.
66
+ *
67
+ * `message` names the answer, which is what a rating is filed under; a bubble
68
+ * that is not an answer says so instead, and has no id to give.
58
69
  */
59
- attach(bubble: HTMLDivElement, options: { rateable?: boolean } = {}): void {
70
+ attach(bubble: HTMLDivElement, message: AgUiMessageIds | Unrateable): void {
60
71
  const enabled = this.#enabled();
61
72
  const copyable = enabled.has(MESSAGE_ACTIONS.COPY);
62
73
  // A failed run is copyable -- error text is what people paste into a bug
63
74
  // report -- but not rateable: a rating is a statement about an *answer*,
64
75
  // and mixing "the connection dropped" into that signal makes the host's
65
76
  // feedback data say less than it did before.
66
- const rateable = options.rateable !== false && enabled.has(MESSAGE_ACTIONS.FEEDBACK);
77
+ const answer = "messageId" in message ? message : null;
78
+ const rateable = answer !== null && enabled.has(MESSAGE_ACTIONS.FEEDBACK);
79
+ // Read now rather than at click time. Every path that moves the element to
80
+ // another thread -- New chat, a switch, a change of principal -- clears
81
+ // the transcript, so today the two agree; the bubble can only be rated
82
+ // while the thread it was drawn in is current. Were a later path to change
83
+ // the thread and keep the bubbles, the thread the message was drawn from is
84
+ // still the one it is stored in, and that is what a host files it under.
85
+ const threadId = this.#host.threadId();
67
86
  if (copyable || rateable) {
68
87
  attachMessageActions(bubble, {
69
88
  strings: this.#host.strings(),
@@ -83,7 +102,16 @@ export class AnswerActions {
83
102
  onFeedback: (rating: "up" | "down") => {
84
103
  this.#host.element.dispatchEvent(
85
104
  new CustomEvent<FeedbackDetail>(FEEDBACK_EVENT, {
86
- detail: { content: copyPayload(bubble).text, rating },
105
+ detail: {
106
+ content: copyPayload(bubble).text,
107
+ rating,
108
+ messageId: answer.messageId,
109
+ threadId,
110
+ // Omitted rather than undefined: a restored message has
111
+ // no run, and a key holding nothing reads as one that
112
+ // was looked up and came back empty.
113
+ ...(answer.runId === undefined ? {} : { runId: answer.runId }),
114
+ },
87
115
  bubbles: true,
88
116
  composed: true,
89
117
  }),
package/src/version.ts CHANGED
@@ -1 +1 @@
1
- export const VERSION: string = "0.43.0";
1
+ export const VERSION: string = "0.44.0";