@artooi/ag-ui-web-component 0.27.0 → 0.29.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 (85) hide show
  1. package/CHANGELOG.md +663 -1
  2. package/README.md +557 -11
  3. package/dist/ag-ui-web-component.bundle.js +294 -36
  4. package/dist/ag-ui-web-component.bundle.js.map +4 -4
  5. package/dist/constants.d.ts +69 -0
  6. package/dist/constants.d.ts.map +1 -1
  7. package/dist/core/ag_ui_chat.d.ts +262 -1
  8. package/dist/core/ag_ui_chat.d.ts.map +1 -1
  9. package/dist/core/agui_client.d.ts +46 -1
  10. package/dist/core/agui_client.d.ts.map +1 -1
  11. package/dist/core/conversation_store.d.ts +43 -1
  12. package/dist/core/conversation_store.d.ts.map +1 -1
  13. package/dist/core/create_http_agent.d.ts +13 -0
  14. package/dist/core/create_http_agent.d.ts.map +1 -1
  15. package/dist/core/remote_conversation_store.d.ts +23 -1
  16. package/dist/core/remote_conversation_store.d.ts.map +1 -1
  17. package/dist/core/utils.d.ts +28 -0
  18. package/dist/core/utils.d.ts.map +1 -1
  19. package/dist/index.d.ts +7 -2
  20. package/dist/index.d.ts.map +1 -1
  21. package/dist/index.js +2104 -194
  22. package/dist/index.js.map +4 -4
  23. package/dist/tools/is_destructive.d.ts +8 -2
  24. package/dist/tools/is_destructive.d.ts.map +1 -1
  25. package/dist/tools/parse_tool_catalog.d.ts +11 -4
  26. package/dist/tools/parse_tool_catalog.d.ts.map +1 -1
  27. package/dist/ui/approval_card.d.ts +18 -0
  28. package/dist/ui/approval_card.d.ts.map +1 -1
  29. package/dist/ui/checkpoint_menu.d.ts +10 -0
  30. package/dist/ui/checkpoint_menu.d.ts.map +1 -1
  31. package/dist/ui/confirmation_card.d.ts +16 -0
  32. package/dist/ui/confirmation_card.d.ts.map +1 -1
  33. package/dist/ui/message_actions.d.ts +46 -0
  34. package/dist/ui/message_actions.d.ts.map +1 -0
  35. package/dist/ui/page_quote_offer.d.ts +33 -0
  36. package/dist/ui/page_quote_offer.d.ts.map +1 -0
  37. package/dist/ui/quote_selection.d.ts +66 -0
  38. package/dist/ui/quote_selection.d.ts.map +1 -0
  39. package/dist/ui/relative_time.d.ts +10 -0
  40. package/dist/ui/relative_time.d.ts.map +1 -1
  41. package/dist/ui/render_markdown.d.ts +23 -5
  42. package/dist/ui/render_markdown.d.ts.map +1 -1
  43. package/dist/ui/resize_handle.d.ts +5 -1
  44. package/dist/ui/resize_handle.d.ts.map +1 -1
  45. package/dist/ui/stick_to_bottom.d.ts +55 -0
  46. package/dist/ui/stick_to_bottom.d.ts.map +1 -0
  47. package/dist/ui/styles.d.ts +1 -1
  48. package/dist/ui/styles.d.ts.map +1 -1
  49. package/dist/ui/suggestion_chips.d.ts +29 -0
  50. package/dist/ui/suggestion_chips.d.ts.map +1 -0
  51. package/dist/ui/thread_drawer.d.ts +10 -0
  52. package/dist/ui/thread_drawer.d.ts.map +1 -1
  53. package/dist/ui/tool_call_card.d.ts +8 -0
  54. package/dist/ui/tool_call_card.d.ts.map +1 -1
  55. package/dist/ui/ui_strings.d.ts +53 -7
  56. package/dist/ui/ui_strings.d.ts.map +1 -1
  57. package/dist/ui/voice_input.d.ts.map +1 -1
  58. package/package.json +1 -1
  59. package/src/constants.ts +75 -0
  60. package/src/core/ag_ui_chat.ts +1357 -113
  61. package/src/core/agui_client.ts +81 -1
  62. package/src/core/conversation_store.ts +128 -42
  63. package/src/core/create_http_agent.ts +24 -2
  64. package/src/core/remote_conversation_store.ts +35 -2
  65. package/src/core/utils.ts +58 -0
  66. package/src/index.ts +39 -0
  67. package/src/tools/is_destructive.ts +8 -2
  68. package/src/tools/parse_tool_catalog.ts +18 -6
  69. package/src/ui/approval_card.ts +90 -2
  70. package/src/ui/checkpoint_menu.ts +22 -5
  71. package/src/ui/confirmation_card.ts +29 -1
  72. package/src/ui/message_actions.ts +158 -0
  73. package/src/ui/page_quote_offer.ts +215 -0
  74. package/src/ui/quote_selection.ts +345 -0
  75. package/src/ui/relative_time.ts +11 -0
  76. package/src/ui/render_markdown.ts +111 -21
  77. package/src/ui/resize_handle.ts +32 -2
  78. package/src/ui/stick_to_bottom.ts +126 -0
  79. package/src/ui/styles.ts +227 -0
  80. package/src/ui/suggestion_chips.ts +73 -0
  81. package/src/ui/thread_drawer.ts +22 -2
  82. package/src/ui/tool_call_card.ts +9 -0
  83. package/src/ui/ui_strings.ts +79 -8
  84. package/src/ui/voice_input.ts +43 -0
  85. package/src/version.ts +1 -1
@@ -5,6 +5,21 @@ import { DEFAULT_UI_STRINGS, type UiStrings } from "./ui_strings.js";
5
5
  /** Lifecycle of the mic button, reflected on its `data-state` for CSS. */
6
6
  type VoiceState = "idle" | "recording" | "transcribing";
7
7
 
8
+ /**
9
+ * How long one recording may run before it stops itself.
10
+ *
11
+ * Two minutes is a ceiling, not a target: dictating into a chat composer is a
12
+ * sentence or two, and two minutes of speech is roughly 350 words — longer than
13
+ * any message this control is for. What it bounds is the case that has no end
14
+ * at all, a mic left live in a forgotten tab: about a megabyte of accumulated
15
+ * Opus, a recording indicator the user is no longer watching, and eventually a
16
+ * multipart upload no client-side check sizes.
17
+ *
18
+ * Hitting it stops and transcribes; the audio is never discarded, because a cap
19
+ * the user was not told about must not cost them the words they already spoke.
20
+ */
21
+ const MAX_RECORDING_MS = 120_000;
22
+
8
23
  /** Construction options for {@link VoiceInput}. */
9
24
  export interface VoiceInputOptions {
10
25
  /** Turns a recorded clip into text (the built-in or a custom transport). */
@@ -39,6 +54,8 @@ export class VoiceInput {
39
54
  #recorder: MediaRecorder | null = null;
40
55
  #stream: MediaStream | null = null;
41
56
  #chunks: Blob[] = [];
57
+ #capTimer: ReturnType<typeof setTimeout> | null = null;
58
+ #hitCap = false;
42
59
  #disposed = false;
43
60
 
44
61
  constructor(options: VoiceInputOptions) {
@@ -84,6 +101,7 @@ export class VoiceInput {
84
101
  }
85
102
  this.#stream = stream;
86
103
  this.#chunks = [];
104
+ this.#hitCap = false;
87
105
  const recorder = new MediaRecorder(stream);
88
106
  recorder.addEventListener("dataavailable", (event) => {
89
107
  this.#chunks.push(event.data);
@@ -93,14 +111,29 @@ export class VoiceInput {
93
111
  });
94
112
  this.#recorder = recorder;
95
113
  recorder.start();
114
+ // Nothing else ends a recording: `MediaRecorder` runs until it is told to
115
+ // stop, so without this the only exits are a second click and `dispose()`.
116
+ this.#capTimer = setTimeout(() => {
117
+ this.#hitCap = true;
118
+ this.#stop();
119
+ }, MAX_RECORDING_MS);
96
120
  this.#setState("recording");
97
121
  }
98
122
 
99
123
  #stop(): void {
124
+ this.#clearCap();
100
125
  // ``stop`` flushes a final ``dataavailable`` then fires ``stop`` → #finish.
101
126
  this.#recorder?.stop();
102
127
  }
103
128
 
129
+ /** Drop the cap timer; recording is over, by whichever route. */
130
+ #clearCap(): void {
131
+ if (this.#capTimer !== null) {
132
+ clearTimeout(this.#capTimer);
133
+ this.#capTimer = null;
134
+ }
135
+ }
136
+
104
137
  /**
105
138
  * Tear the control down, for a host element removed mid-recording. Stops any
106
139
  * live `MediaRecorder`, releases the mic tracks so the browser's recording
@@ -109,6 +142,7 @@ export class VoiceInput {
109
142
  */
110
143
  dispose(): void {
111
144
  this.#disposed = true;
145
+ this.#clearCap();
112
146
  if (this.#recorder !== null && this.#recorder.state !== "inactive") {
113
147
  this.#recorder.stop();
114
148
  }
@@ -126,6 +160,15 @@ export class VoiceInput {
126
160
  try {
127
161
  const text = await this.#transcribe(audio);
128
162
  this.#setState("idle");
163
+ if (this.#hitCap) {
164
+ // #setState has just reset the tooltip to the idle label, so this goes
165
+ // after it. It says why the mic went quiet on its own — the transcript
166
+ // below is the proof nothing was thrown away.
167
+ this.element.title = this.#strings.recordingLimit.replace(
168
+ "{n}",
169
+ String(MAX_RECORDING_MS / 60_000),
170
+ );
171
+ }
129
172
  if (text !== "") {
130
173
  this.#onText(text);
131
174
  }
package/src/version.ts CHANGED
@@ -1 +1 @@
1
- export const VERSION: string = "0.27.0";
1
+ export const VERSION: string = "0.29.0";