@dudousxd/nestjs-agent-react 0.18.0 → 0.20.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/dist/index.cjs CHANGED
@@ -35,6 +35,7 @@ __export(src_exports, {
35
35
  AgentChatTransport: () => AgentChatTransport,
36
36
  AgentClient: () => AgentClient,
37
37
  AgentHttpError: () => AgentHttpError,
38
+ AmbientRenderUiContext: () => AmbientRenderUiContext,
38
39
  ChatInput: () => ChatInput,
39
40
  DEFAULT_SPEECH_LANG: () => DEFAULT_SPEECH_LANG,
40
41
  MessageItem: () => MessageItem,
@@ -81,6 +82,7 @@ __export(src_exports, {
81
82
  toolCatalogFrom: () => toolCatalogFrom,
82
83
  useAgentChat: () => useAgentChat,
83
84
  useAgents: () => useAgents,
85
+ useAmbientRenderUi: () => useAmbientRenderUi,
84
86
  useApprovalCountdown: () => useApprovalCountdown,
85
87
  useAttachments: () => useAttachments,
86
88
  useChatTranscript: () => useChatTranscript,
@@ -223,6 +225,9 @@ var AgentClient = class {
223
225
  * what a caller then rides on `sendMessage({ text }, { body: { attachments: [...] } })`.
224
226
  */
225
227
  async uploadAttachment(file, options = {}) {
228
+ if (this.options.attachments !== void 0) {
229
+ return this.options.attachments(file, options, this.connection());
230
+ }
226
231
  if (options.onProgress !== void 0 && this.options.fetch === void 0 && typeof XMLHttpRequest !== "undefined") {
227
232
  return this.uploadWithProgress(file, options);
228
233
  }
@@ -337,6 +342,15 @@ var AgentClient = class {
337
342
  fetchImpl() {
338
343
  return this.options.fetch ?? globalThis.fetch;
339
344
  }
345
+ /** This client's connection, for an {@link AttachmentUploadStrategy}. */
346
+ connection() {
347
+ return {
348
+ baseUrl: this.baseUrl(),
349
+ headers: /* @__PURE__ */ __name(() => this.resolveHeaders(), "headers"),
350
+ fetch: this.fetchImpl(),
351
+ ...this.credentials()
352
+ };
353
+ }
340
354
  baseUrl() {
341
355
  return (this.options.baseUrl ?? "").replace(/\/$/, "");
342
356
  }
@@ -1850,11 +1864,29 @@ function backgroundRunsFromThread(messages) {
1850
1864
  }
1851
1865
  __name(backgroundRunsFromThread, "backgroundRunsFromThread");
1852
1866
 
1867
+ // src/components/ambient-ui.ts
1868
+ var import_react9 = require("react");
1869
+ function sharedContext(key) {
1870
+ const symbol = Symbol.for(key);
1871
+ const holder = globalThis;
1872
+ const existing = holder[symbol];
1873
+ if (existing !== void 0) return existing;
1874
+ const created = (0, import_react9.createContext)(null);
1875
+ holder[symbol] = created;
1876
+ return created;
1877
+ }
1878
+ __name(sharedContext, "sharedContext");
1879
+ var AmbientRenderUiContext = sharedContext("@dudousxd/nestjs-agent-react:ambient-render-ui");
1880
+ function useAmbientRenderUi() {
1881
+ return (0, import_react9.useContext)(AmbientRenderUiContext);
1882
+ }
1883
+ __name(useAmbientRenderUi, "useAmbientRenderUi");
1884
+
1853
1885
  // src/components/chat-input.tsx
1854
- var import_react10 = __toESM(require("react"), 1);
1886
+ var import_react11 = __toESM(require("react"), 1);
1855
1887
 
1856
1888
  // src/components/use-speech-recognition.ts
1857
- var import_react9 = require("react");
1889
+ var import_react10 = require("react");
1858
1890
  function getRecognitionCtor() {
1859
1891
  if (typeof window === "undefined") return null;
1860
1892
  const scope = window;
@@ -1862,15 +1894,15 @@ function getRecognitionCtor() {
1862
1894
  }
1863
1895
  __name(getRecognitionCtor, "getRecognitionCtor");
1864
1896
  function useSpeechRecognition({ lang = "en-US", onFinalTranscript, onInterimTranscript }) {
1865
- const recognitionRef = (0, import_react9.useRef)(null);
1866
- const [isListening, setIsListening] = (0, import_react9.useState)(false);
1867
- const ctor = (0, import_react9.useMemo)(() => getRecognitionCtor(), []);
1897
+ const recognitionRef = (0, import_react10.useRef)(null);
1898
+ const [isListening, setIsListening] = (0, import_react10.useState)(false);
1899
+ const ctor = (0, import_react10.useMemo)(() => getRecognitionCtor(), []);
1868
1900
  const isSupported = ctor !== null;
1869
- const finalRef = (0, import_react9.useRef)(onFinalTranscript);
1870
- const interimRef = (0, import_react9.useRef)(onInterimTranscript);
1901
+ const finalRef = (0, import_react10.useRef)(onFinalTranscript);
1902
+ const interimRef = (0, import_react10.useRef)(onInterimTranscript);
1871
1903
  finalRef.current = onFinalTranscript;
1872
1904
  interimRef.current = onInterimTranscript;
1873
- (0, import_react9.useEffect)(() => {
1905
+ (0, import_react10.useEffect)(() => {
1874
1906
  if (!ctor) return;
1875
1907
  const recognition = new ctor();
1876
1908
  recognition.lang = lang;
@@ -1909,7 +1941,7 @@ function useSpeechRecognition({ lang = "en-US", onFinalTranscript, onInterimTran
1909
1941
  ctor,
1910
1942
  lang
1911
1943
  ]);
1912
- const start = (0, import_react9.useCallback)(() => {
1944
+ const start = (0, import_react10.useCallback)(() => {
1913
1945
  const recognition = recognitionRef.current;
1914
1946
  if (!recognition) return;
1915
1947
  try {
@@ -1919,7 +1951,7 @@ function useSpeechRecognition({ lang = "en-US", onFinalTranscript, onInterimTran
1919
1951
  console.warn("SpeechRecognition start failed", error);
1920
1952
  }
1921
1953
  }, []);
1922
- const stop = (0, import_react9.useCallback)(() => {
1954
+ const stop = (0, import_react10.useCallback)(() => {
1923
1955
  const recognition = recognitionRef.current;
1924
1956
  if (!recognition) return;
1925
1957
  try {
@@ -1938,8 +1970,8 @@ __name(useSpeechRecognition, "useSpeechRecognition");
1938
1970
 
1939
1971
  // src/components/chat-input.tsx
1940
1972
  function ChatInput({ onSubmit, disabled, placeholder, rows = 2, enableSpeech = true, speechLang = "en-US", sendLabel = "Send", onStop, isStreaming = false, stopLabel = "Stop generating", className, textareaClassName, sendButtonClassName, micButtonClassName, stopButtonClassName, renderMic }) {
1941
- const [value, setValue] = (0, import_react10.useState)("");
1942
- const [interim, setInterim] = (0, import_react10.useState)("");
1973
+ const [value, setValue] = (0, import_react11.useState)("");
1974
+ const [interim, setInterim] = (0, import_react11.useState)("");
1943
1975
  const speech = useSpeechRecognition({
1944
1976
  lang: speechLang,
1945
1977
  onFinalTranscript: /* @__PURE__ */ __name((text) => {
@@ -1950,7 +1982,7 @@ function ChatInput({ onSubmit, disabled, placeholder, rows = 2, enableSpeech = t
1950
1982
  }, "onFinalTranscript"),
1951
1983
  onInterimTranscript: /* @__PURE__ */ __name((text) => setInterim(text), "onInterimTranscript")
1952
1984
  });
1953
- (0, import_react10.useEffect)(() => {
1985
+ (0, import_react11.useEffect)(() => {
1954
1986
  if (!speech.isListening) setInterim("");
1955
1987
  }, [
1956
1988
  speech.isListening
@@ -1978,9 +2010,9 @@ function ChatInput({ onSubmit, disabled, placeholder, rows = 2, enableSpeech = t
1978
2010
  const displayValue = speech.isListening && interim ? `${value}${value && !value.endsWith(" ") ? " " : ""}${interim}` : value;
1979
2011
  const showMic = enableSpeech && speech.isSupported;
1980
2012
  const showStop = isStreaming && onStop !== void 0;
1981
- return /* @__PURE__ */ import_react10.default.createElement("div", {
2013
+ return /* @__PURE__ */ import_react11.default.createElement("div", {
1982
2014
  className
1983
- }, /* @__PURE__ */ import_react10.default.createElement("textarea", {
2015
+ }, /* @__PURE__ */ import_react11.default.createElement("textarea", {
1984
2016
  className: textareaClassName,
1985
2017
  rows,
1986
2018
  value: displayValue,
@@ -1991,17 +2023,17 @@ function ChatInput({ onSubmit, disabled, placeholder, rows = 2, enableSpeech = t
1991
2023
  }, "onChange"),
1992
2024
  onKeyDown: handleKeyDown,
1993
2025
  placeholder: placeholder ?? "Ask something (Enter to send, Shift+Enter for newline)"
1994
- }), /* @__PURE__ */ import_react10.default.createElement("button", {
2026
+ }), /* @__PURE__ */ import_react11.default.createElement("button", {
1995
2027
  type: "button",
1996
2028
  className: sendButtonClassName,
1997
2029
  onClick: submit,
1998
2030
  disabled: disabled || !value.trim()
1999
- }, sendLabel), showStop ? /* @__PURE__ */ import_react10.default.createElement("button", {
2031
+ }, sendLabel), showStop ? /* @__PURE__ */ import_react11.default.createElement("button", {
2000
2032
  type: "button",
2001
2033
  className: stopButtonClassName,
2002
2034
  onClick: /* @__PURE__ */ __name(() => void onStop(), "onClick"),
2003
2035
  "aria-label": "Stop generating"
2004
- }, stopLabel) : null, showMic ? /* @__PURE__ */ import_react10.default.createElement("button", {
2036
+ }, stopLabel) : null, showMic ? /* @__PURE__ */ import_react11.default.createElement("button", {
2005
2037
  type: "button",
2006
2038
  className: micButtonClassName,
2007
2039
  onClick: toggleMic,
@@ -2014,10 +2046,10 @@ function ChatInput({ onSubmit, disabled, placeholder, rows = 2, enableSpeech = t
2014
2046
  __name(ChatInput, "ChatInput");
2015
2047
 
2016
2048
  // src/components/message-item.tsx
2017
- var import_react13 = __toESM(require("react"), 1);
2049
+ var import_react14 = __toESM(require("react"), 1);
2018
2050
 
2019
2051
  // src/transcript/use-chat-transcript.ts
2020
- var import_react12 = require("react");
2052
+ var import_react13 = require("react");
2021
2053
 
2022
2054
  // src/transcript/model.ts
2023
2055
  var import_nestjs_agent_core2 = require("@dudousxd/nestjs-agent-core");
@@ -2994,11 +3026,11 @@ function formatCostUsd(cost) {
2994
3026
  __name(formatCostUsd, "formatCostUsd");
2995
3027
 
2996
3028
  // src/transcript/use-stick-to-bottom.ts
2997
- var import_react11 = require("react");
3029
+ var import_react12 = require("react");
2998
3030
  function useStickToBottom({ contentKey, threshold = 32 }) {
2999
- const containerRef = (0, import_react11.useRef)(null);
3000
- const [isAtBottom, setIsAtBottom] = (0, import_react11.useState)(true);
3001
- const measure = (0, import_react11.useCallback)(() => {
3031
+ const containerRef = (0, import_react12.useRef)(null);
3032
+ const [isAtBottom, setIsAtBottom] = (0, import_react12.useState)(true);
3033
+ const measure = (0, import_react12.useCallback)(() => {
3002
3034
  const element = containerRef.current;
3003
3035
  if (!element) {
3004
3036
  return;
@@ -3008,7 +3040,7 @@ function useStickToBottom({ contentKey, threshold = 32 }) {
3008
3040
  }, [
3009
3041
  threshold
3010
3042
  ]);
3011
- const scrollToBottom = (0, import_react11.useCallback)(() => {
3043
+ const scrollToBottom = (0, import_react12.useCallback)(() => {
3012
3044
  const element = containerRef.current;
3013
3045
  if (!element) {
3014
3046
  return;
@@ -3016,7 +3048,7 @@ function useStickToBottom({ contentKey, threshold = 32 }) {
3016
3048
  element.scrollTop = element.scrollHeight;
3017
3049
  setIsAtBottom(true);
3018
3050
  }, []);
3019
- const setContainer = (0, import_react11.useCallback)((element) => {
3051
+ const setContainer = (0, import_react12.useCallback)((element) => {
3020
3052
  containerRef.current = element;
3021
3053
  if (element) {
3022
3054
  measure();
@@ -3024,7 +3056,7 @@ function useStickToBottom({ contentKey, threshold = 32 }) {
3024
3056
  }, [
3025
3057
  measure
3026
3058
  ]);
3027
- (0, import_react11.useEffect)(() => {
3059
+ (0, import_react12.useEffect)(() => {
3028
3060
  if (isAtBottom) {
3029
3061
  scrollToBottom();
3030
3062
  }
@@ -3033,7 +3065,7 @@ function useStickToBottom({ contentKey, threshold = 32 }) {
3033
3065
  isAtBottom,
3034
3066
  scrollToBottom
3035
3067
  ]);
3036
- const getContainerProps = (0, import_react11.useCallback)(() => ({
3068
+ const getContainerProps = (0, import_react12.useCallback)(() => ({
3037
3069
  ref: setContainer,
3038
3070
  onScroll: measure
3039
3071
  }), [
@@ -3055,14 +3087,14 @@ var DEFAULT_LOAD_EARLIER_STEP = 50;
3055
3087
  var DEFAULT_COPY_RESET_MS = 1500;
3056
3088
  function useChatTranscript(options) {
3057
3089
  const { messages, status, initialVisibleCount = DEFAULT_VISIBLE_COUNT, loadEarlierStep = DEFAULT_LOAD_EARLIER_STEP, followUps, stickToBottomThreshold } = options;
3058
- const latest = (0, import_react12.useRef)(options);
3090
+ const latest = (0, import_react13.useRef)(options);
3059
3091
  latest.current = options;
3060
- const [visibleCount, setVisibleCount] = (0, import_react12.useState)(initialVisibleCount);
3061
- const [stopRequested, setStopRequested] = (0, import_react12.useState)(false);
3092
+ const [visibleCount, setVisibleCount] = (0, import_react13.useState)(initialVisibleCount);
3093
+ const [stopRequested, setStopRequested] = (0, import_react13.useState)(false);
3062
3094
  const isStreaming = status === "streaming" || status === "reconnecting";
3063
3095
  const isBusy = status === "submitted" || isStreaming;
3064
3096
  const isEmpty = messages.length === 0;
3065
- (0, import_react12.useEffect)(() => {
3097
+ (0, import_react13.useEffect)(() => {
3066
3098
  if (!isBusy) {
3067
3099
  setStopRequested(false);
3068
3100
  }
@@ -3079,7 +3111,7 @@ function useChatTranscript(options) {
3079
3111
  streamingMessageId,
3080
3112
  options
3081
3113
  });
3082
- const stop = (0, import_react12.useCallback)(() => {
3114
+ const stop = (0, import_react13.useCallback)(() => {
3083
3115
  const current = latest.current;
3084
3116
  if (current.status !== "submitted" && current.status !== "streaming" && current.status !== "reconnecting") {
3085
3117
  return;
@@ -3087,8 +3119,8 @@ function useChatTranscript(options) {
3087
3119
  setStopRequested(true);
3088
3120
  void current.onStop?.();
3089
3121
  }, []);
3090
- const loadEarlier = (0, import_react12.useCallback)(() => setVisibleCount((count) => count + (latest.current.loadEarlierStep ?? DEFAULT_LOAD_EARLIER_STEP)), []);
3091
- const showAll = (0, import_react12.useCallback)(() => setVisibleCount(latest.current.messages.length), []);
3122
+ const loadEarlier = (0, import_react13.useCallback)(() => setVisibleCount((count) => count + (latest.current.loadEarlierStep ?? DEFAULT_LOAD_EARLIER_STEP)), []);
3123
+ const showAll = (0, import_react13.useCallback)(() => setVisibleCount(latest.current.messages.length), []);
3092
3124
  const scroll = useStickToBottom({
3093
3125
  contentKey: contentSignature(messages),
3094
3126
  ...stickToBottomThreshold !== void 0 ? {
@@ -3124,7 +3156,7 @@ function useChatTranscript(options) {
3124
3156
  __name(useChatTranscript, "useChatTranscript");
3125
3157
  function useTranscriptItem(options) {
3126
3158
  const { message, isStreaming = false } = options;
3127
- const messagesRef = (0, import_react12.useRef)([
3159
+ const messagesRef = (0, import_react13.useRef)([
3128
3160
  message
3129
3161
  ]);
3130
3162
  if (messagesRef.current[0] !== message) {
@@ -3142,13 +3174,13 @@ function useTranscriptItem(options) {
3142
3174
  }
3143
3175
  __name(useTranscriptItem, "useTranscriptItem");
3144
3176
  function useTranscriptItems({ messages, visibleStart, streamingMessageId, options }) {
3145
- const [drafts, setDrafts] = (0, import_react12.useState)(() => /* @__PURE__ */ new Map());
3146
- const [copied, setCopied] = (0, import_react12.useState)(() => /* @__PURE__ */ new Set());
3147
- const [openReasoning, setOpenReasoning] = (0, import_react12.useState)(() => /* @__PURE__ */ new Map());
3148
- const [picks, setPicks] = (0, import_react12.useState)(() => /* @__PURE__ */ new Map());
3149
- const [settling, setSettling] = (0, import_react12.useState)(() => /* @__PURE__ */ new Map());
3150
- const [settleErrors, setSettleErrors] = (0, import_react12.useState)(() => /* @__PURE__ */ new Map());
3151
- const latest = (0, import_react12.useRef)({
3177
+ const [drafts, setDrafts] = (0, import_react13.useState)(() => /* @__PURE__ */ new Map());
3178
+ const [copied, setCopied] = (0, import_react13.useState)(() => /* @__PURE__ */ new Set());
3179
+ const [openReasoning, setOpenReasoning] = (0, import_react13.useState)(() => /* @__PURE__ */ new Map());
3180
+ const [picks, setPicks] = (0, import_react13.useState)(() => /* @__PURE__ */ new Map());
3181
+ const [settling, setSettling] = (0, import_react13.useState)(() => /* @__PURE__ */ new Map());
3182
+ const [settleErrors, setSettleErrors] = (0, import_react13.useState)(() => /* @__PURE__ */ new Map());
3183
+ const latest = (0, import_react13.useRef)({
3152
3184
  options,
3153
3185
  drafts,
3154
3186
  picks,
@@ -3160,23 +3192,23 @@ function useTranscriptItems({ messages, visibleStart, streamingMessageId, option
3160
3192
  picks,
3161
3193
  messages
3162
3194
  };
3163
- const copyTimers = (0, import_react12.useRef)(/* @__PURE__ */ new Map());
3164
- (0, import_react12.useEffect)(() => () => {
3195
+ const copyTimers = (0, import_react13.useRef)(/* @__PURE__ */ new Map());
3196
+ (0, import_react13.useEffect)(() => () => {
3165
3197
  for (const timer of copyTimers.current.values()) {
3166
3198
  clearTimeout(timer);
3167
3199
  }
3168
3200
  copyTimers.current.clear();
3169
3201
  }, []);
3170
- const callbackCache = (0, import_react12.useRef)(/* @__PURE__ */ new Map());
3171
- const reasoningToggleCache = (0, import_react12.useRef)(/* @__PURE__ */ new Map());
3172
- const toggleReasoning = (0, import_react12.useCallback)((key, open) => {
3202
+ const callbackCache = (0, import_react13.useRef)(/* @__PURE__ */ new Map());
3203
+ const reasoningToggleCache = (0, import_react13.useRef)(/* @__PURE__ */ new Map());
3204
+ const toggleReasoning = (0, import_react13.useCallback)((key, open) => {
3173
3205
  setOpenReasoning((current) => {
3174
3206
  const next = new Map(current);
3175
3207
  next.set(key, open ?? !(current.get(key) ?? false));
3176
3208
  return next;
3177
3209
  });
3178
3210
  }, []);
3179
- const stableToggle = (0, import_react12.useCallback)((key) => {
3211
+ const stableToggle = (0, import_react13.useCallback)((key) => {
3180
3212
  let cached = reasoningToggleCache.current.get(key);
3181
3213
  if (!cached) {
3182
3214
  cached = /* @__PURE__ */ __name((open) => toggleReasoning(key, open), "cached");
@@ -3186,10 +3218,10 @@ function useTranscriptItems({ messages, visibleStart, streamingMessageId, option
3186
3218
  }, [
3187
3219
  toggleReasoning
3188
3220
  ]);
3189
- const pick = (0, import_react12.useCallback)((toolCallId, questionId, values) => {
3221
+ const pick = (0, import_react13.useCallback)((toolCallId, questionId, values) => {
3190
3222
  setPicks((current) => new Map(current).set(pickKey(toolCallId, questionId), values));
3191
3223
  }, []);
3192
- const settle = (0, import_react12.useCallback)((toolCallId, action, send) => {
3224
+ const settle = (0, import_react13.useCallback)((toolCallId, action, send) => {
3193
3225
  setSettleErrors((current) => {
3194
3226
  if (!current.has(toolCallId)) {
3195
3227
  return current;
@@ -3213,7 +3245,7 @@ function useTranscriptItems({ messages, visibleStart, streamingMessageId, option
3213
3245
  failed(error);
3214
3246
  }
3215
3247
  }, []);
3216
- const answer = (0, import_react12.useCallback)((toolCallId) => {
3248
+ const answer = (0, import_react13.useCallback)((toolCallId) => {
3217
3249
  const current = latest.current;
3218
3250
  const onAnswer = current.options.onAnswer;
3219
3251
  if (!onAnswer) {
@@ -3223,7 +3255,7 @@ function useTranscriptItems({ messages, visibleStart, streamingMessageId, option
3223
3255
  }, [
3224
3256
  settle
3225
3257
  ]);
3226
- const skip = (0, import_react12.useCallback)((toolCallId) => {
3258
+ const skip = (0, import_react13.useCallback)((toolCallId) => {
3227
3259
  const onSkip = latest.current.options.onSkip;
3228
3260
  if (onSkip) {
3229
3261
  settle(toolCallId, "skip", () => onSkip(toolCallId));
@@ -3231,7 +3263,7 @@ function useTranscriptItems({ messages, visibleStart, streamingMessageId, option
3231
3263
  }, [
3232
3264
  settle
3233
3265
  ]);
3234
- const approve = (0, import_react12.useCallback)((toolCallId, options2) => {
3266
+ const approve = (0, import_react13.useCallback)((toolCallId, options2) => {
3235
3267
  const onApprove = latest.current.options.onApprove;
3236
3268
  if (onApprove) {
3237
3269
  settle(toolCallId, "approve", () => options2 === void 0 ? onApprove(toolCallId) : onApprove(toolCallId, options2));
@@ -3239,7 +3271,7 @@ function useTranscriptItems({ messages, visibleStart, streamingMessageId, option
3239
3271
  }, [
3240
3272
  settle
3241
3273
  ]);
3242
- const reject = (0, import_react12.useCallback)((toolCallId) => {
3274
+ const reject = (0, import_react13.useCallback)((toolCallId) => {
3243
3275
  const onReject = latest.current.options.onReject;
3244
3276
  if (onReject) {
3245
3277
  settle(toolCallId, "reject", () => onReject(toolCallId));
@@ -3247,7 +3279,7 @@ function useTranscriptItems({ messages, visibleStart, streamingMessageId, option
3247
3279
  }, [
3248
3280
  settle
3249
3281
  ]);
3250
- const callbacksFor = (0, import_react12.useCallback)((id) => {
3282
+ const callbacksFor = (0, import_react13.useCallback)((id) => {
3251
3283
  const cached = callbackCache.current.get(id);
3252
3284
  if (cached) {
3253
3285
  return cached;
@@ -3489,59 +3521,64 @@ function MessageItem({ message, isStreaming = false, editable, onEditSubmit, reg
3489
3521
  getCreatedAt: /* @__PURE__ */ __name(() => createdAt, "getCreatedAt")
3490
3522
  } : {}
3491
3523
  });
3492
- return /* @__PURE__ */ import_react13.default.createElement(MessageItemView, {
3524
+ return /* @__PURE__ */ import_react14.default.createElement(MessageItemView, {
3493
3525
  item,
3494
3526
  ...slots
3495
3527
  });
3496
3528
  }
3497
3529
  __name(MessageItem, "MessageItem");
3498
- function MessageItemView({ item, ...slots }) {
3530
+ function MessageItemView({ item, ...given }) {
3531
+ const ambientRenderUi = useAmbientRenderUi();
3532
+ const slots = given.renderUi === void 0 && ambientRenderUi !== null ? {
3533
+ ...given,
3534
+ renderUi: ambientRenderUi
3535
+ } : given;
3499
3536
  const { classNames } = slots;
3500
- const actionRow = /* @__PURE__ */ import_react13.default.createElement("div", {
3537
+ const actionRow = /* @__PURE__ */ import_react14.default.createElement("div", {
3501
3538
  className: classNames?.actions,
3502
3539
  "data-actions-for": item.role
3503
- }, item.copy.available ? /* @__PURE__ */ import_react13.default.createElement("button", {
3540
+ }, item.copy.available ? /* @__PURE__ */ import_react14.default.createElement("button", {
3504
3541
  type: "button",
3505
3542
  onClick: item.copy.copy,
3506
3543
  className: classNames?.actionButton,
3507
3544
  title: item.copy.copied ? "Copied!" : "Copy message text"
3508
- }, item.copy.copied ? "Copied" : "Copy") : null, item.fork.available ? /* @__PURE__ */ import_react13.default.createElement("button", {
3545
+ }, item.copy.copied ? "Copied" : "Copy") : null, item.fork.available ? /* @__PURE__ */ import_react14.default.createElement("button", {
3509
3546
  type: "button",
3510
3547
  onClick: item.fork.run,
3511
3548
  className: classNames?.actionButton,
3512
3549
  title: "Fork thread from this message"
3513
- }, "Fork") : null, item.regenerate.available ? /* @__PURE__ */ import_react13.default.createElement("button", {
3550
+ }, "Fork") : null, item.regenerate.available ? /* @__PURE__ */ import_react14.default.createElement("button", {
3514
3551
  type: "button",
3515
3552
  onClick: item.regenerate.run,
3516
3553
  className: classNames?.actionButton,
3517
3554
  title: "Regenerate response"
3518
- }, "Regenerate") : null, slots.meta, !item.isUser && item.usage ? /* @__PURE__ */ import_react13.default.createElement("span", {
3555
+ }, "Regenerate") : null, slots.meta, !item.isUser && item.usage ? /* @__PURE__ */ import_react14.default.createElement("span", {
3519
3556
  className: classNames?.usage,
3520
3557
  title: `Input ${item.usage.inputTokens.toLocaleString()} \xB7 Output ${item.usage.outputTokens.toLocaleString()} tokens`
3521
- }, item.usage.costLabel, " \xB7 ", item.usage.tokensLabel) : null, item.timestamp ? /* @__PURE__ */ import_react13.default.createElement("span", {
3558
+ }, item.usage.costLabel, " \xB7 ", item.usage.tokensLabel) : null, item.timestamp ? /* @__PURE__ */ import_react14.default.createElement("span", {
3522
3559
  className: classNames?.timestamp,
3523
3560
  title: item.timestamp.absolute
3524
3561
  }, item.timestamp.relative) : null);
3525
3562
  if (item.edit.available) {
3526
- return /* @__PURE__ */ import_react13.default.createElement(EditableUserBubble, {
3563
+ return /* @__PURE__ */ import_react14.default.createElement(EditableUserBubble, {
3527
3564
  item,
3528
3565
  slots,
3529
3566
  actions: actionRow
3530
3567
  });
3531
3568
  }
3532
3569
  const className = joinClasses(classNames?.root, classNames?.byRole?.[item.role]);
3533
- return /* @__PURE__ */ import_react13.default.createElement("div", {
3570
+ return /* @__PURE__ */ import_react14.default.createElement("div", {
3534
3571
  className,
3535
3572
  "data-role": item.role,
3536
3573
  "data-streaming": item.isStreaming ? "true" : void 0
3537
- }, /* @__PURE__ */ import_react13.default.createElement("div", null, renderBlocks(item, slots)), actionRow);
3574
+ }, /* @__PURE__ */ import_react14.default.createElement("div", null, renderBlocks(item, slots)), actionRow);
3538
3575
  }
3539
3576
  __name(MessageItemView, "MessageItemView");
3540
3577
  function renderBlocks(item, slots) {
3541
3578
  const nodes = [];
3542
3579
  for (const block of item.blocks) {
3543
3580
  if (block.kind === "text") {
3544
- nodes.push(/* @__PURE__ */ import_react13.default.createElement("div", {
3581
+ nodes.push(/* @__PURE__ */ import_react14.default.createElement("div", {
3545
3582
  key: block.key,
3546
3583
  className: slots.classNames?.text
3547
3584
  }, slots.renderText ? slots.renderText(block.text, {
@@ -3562,7 +3599,7 @@ function renderBlocks(item, slots) {
3562
3599
  continue;
3563
3600
  }
3564
3601
  if (block.kind === "ui" && slots.renderUi) {
3565
- nodes.push(/* @__PURE__ */ import_react13.default.createElement("div", {
3602
+ nodes.push(/* @__PURE__ */ import_react14.default.createElement("div", {
3566
3603
  key: block.key,
3567
3604
  "data-slot": "ui",
3568
3605
  "data-component": block.component
@@ -3573,18 +3610,18 @@ function renderBlocks(item, slots) {
3573
3610
  }
3574
3611
  __name(renderBlocks, "renderBlocks");
3575
3612
  function renderFilesBlock(block, slots) {
3576
- return /* @__PURE__ */ import_react13.default.createElement("div", {
3613
+ return /* @__PURE__ */ import_react14.default.createElement("div", {
3577
3614
  key: block.key,
3578
3615
  className: slots.classNames?.files,
3579
3616
  "data-files": "true"
3580
- }, slots.renderFiles ? slots.renderFiles(block.files) : block.files.map((file) => /* @__PURE__ */ import_react13.default.createElement("a", {
3617
+ }, slots.renderFiles ? slots.renderFiles(block.files) : block.files.map((file) => /* @__PURE__ */ import_react14.default.createElement("a", {
3581
3618
  key: file.url,
3582
3619
  href: file.url,
3583
3620
  target: "_blank",
3584
3621
  rel: "noreferrer",
3585
3622
  className: slots.classNames?.file,
3586
3623
  title: file.filename ?? file.mediaType
3587
- }, file.isImage ? /* @__PURE__ */ import_react13.default.createElement("img", {
3624
+ }, file.isImage ? /* @__PURE__ */ import_react14.default.createElement("img", {
3588
3625
  src: file.url,
3589
3626
  alt: file.filename ?? "image",
3590
3627
  className: slots.classNames?.fileImage
@@ -3592,17 +3629,17 @@ function renderFilesBlock(block, slots) {
3592
3629
  }
3593
3630
  __name(renderFilesBlock, "renderFilesBlock");
3594
3631
  function renderReasoningBlock(block, slots) {
3595
- return /* @__PURE__ */ import_react13.default.createElement("div", {
3632
+ return /* @__PURE__ */ import_react14.default.createElement("div", {
3596
3633
  key: block.key,
3597
3634
  className: slots.classNames?.reasoning,
3598
3635
  "data-reasoning": "true",
3599
3636
  "data-streaming": block.isStreaming ? "true" : void 0
3600
- }, /* @__PURE__ */ import_react13.default.createElement("button", {
3637
+ }, /* @__PURE__ */ import_react14.default.createElement("button", {
3601
3638
  type: "button",
3602
3639
  className: slots.classNames?.reasoningToggle,
3603
3640
  onClick: /* @__PURE__ */ __name(() => block.toggle(), "onClick"),
3604
3641
  "aria-expanded": block.isOpen
3605
- }, slots.reasoningLabel ?? "Reasoning"), block.isOpen ? /* @__PURE__ */ import_react13.default.createElement("div", {
3642
+ }, slots.reasoningLabel ?? "Reasoning"), block.isOpen ? /* @__PURE__ */ import_react14.default.createElement("div", {
3606
3643
  className: slots.classNames?.reasoningText
3607
3644
  }, slots.renderReasoning ? slots.renderReasoning(block.text, {
3608
3645
  isStreaming: block.isStreaming,
@@ -3613,7 +3650,7 @@ __name(renderReasoningBlock, "renderReasoningBlock");
3613
3650
  function renderToolBlock(item, block, slots) {
3614
3651
  if (slots.renderToolGroup) {
3615
3652
  return [
3616
- /* @__PURE__ */ import_react13.default.createElement(import_react13.default.Fragment, {
3653
+ /* @__PURE__ */ import_react14.default.createElement(import_react14.default.Fragment, {
3617
3654
  key: block.key
3618
3655
  }, slots.renderToolGroup(block.parts, block.key))
3619
3656
  ];
@@ -3624,7 +3661,7 @@ function renderToolBlock(item, block, slots) {
3624
3661
  const renderToolPart = slots.renderToolPart;
3625
3662
  return block.parts.map((part) => {
3626
3663
  const partKey = `${item.id}-${part.toolCallId}`;
3627
- return /* @__PURE__ */ import_react13.default.createElement(import_react13.default.Fragment, {
3664
+ return /* @__PURE__ */ import_react14.default.createElement(import_react14.default.Fragment, {
3628
3665
  key: partKey
3629
3666
  }, renderToolPart(part, partKey));
3630
3667
  });
@@ -3634,14 +3671,14 @@ function EditableUserBubble({ item, slots, actions }) {
3634
3671
  const { classNames } = slots;
3635
3672
  const { edit } = item;
3636
3673
  if (!edit.isEditing) {
3637
- return /* @__PURE__ */ import_react13.default.createElement("div", {
3674
+ return /* @__PURE__ */ import_react14.default.createElement("div", {
3638
3675
  className: joinClasses(classNames?.root, classNames?.byRole?.user),
3639
3676
  "data-role": "user"
3640
- }, /* @__PURE__ */ import_react13.default.createElement("div", {
3677
+ }, /* @__PURE__ */ import_react14.default.createElement("div", {
3641
3678
  className: classNames?.text
3642
3679
  }, slots.renderText ? slots.renderText(item.text, {
3643
3680
  isStreaming: false
3644
- }) : item.text), /* @__PURE__ */ import_react13.default.createElement("button", {
3681
+ }) : item.text), /* @__PURE__ */ import_react14.default.createElement("button", {
3645
3682
  type: "button",
3646
3683
  onClick: edit.start,
3647
3684
  className: classNames?.actionButton,
@@ -3649,18 +3686,18 @@ function EditableUserBubble({ item, slots, actions }) {
3649
3686
  }, "Edit"), actions);
3650
3687
  }
3651
3688
  const textareaProps = edit.getTextareaProps();
3652
- return /* @__PURE__ */ import_react13.default.createElement("div", {
3689
+ return /* @__PURE__ */ import_react14.default.createElement("div", {
3653
3690
  "data-editing": "true"
3654
- }, /* @__PURE__ */ import_react13.default.createElement("textarea", {
3691
+ }, /* @__PURE__ */ import_react14.default.createElement("textarea", {
3655
3692
  ...textareaProps,
3656
3693
  rows: Math.min(8, edit.draft.split("\n").length + 1),
3657
3694
  className: classNames?.editTextarea
3658
- }), /* @__PURE__ */ import_react13.default.createElement("div", {
3695
+ }), /* @__PURE__ */ import_react14.default.createElement("div", {
3659
3696
  className: classNames?.editActions
3660
- }, /* @__PURE__ */ import_react13.default.createElement("button", {
3697
+ }, /* @__PURE__ */ import_react14.default.createElement("button", {
3661
3698
  type: "button",
3662
3699
  onClick: edit.cancel
3663
- }, "Cancel"), /* @__PURE__ */ import_react13.default.createElement("button", {
3700
+ }, "Cancel"), /* @__PURE__ */ import_react14.default.createElement("button", {
3664
3701
  type: "button",
3665
3702
  onClick: edit.save,
3666
3703
  disabled: !edit.canSave
@@ -3904,35 +3941,35 @@ function toItem(entry) {
3904
3941
  __name(toItem, "toItem");
3905
3942
 
3906
3943
  // src/composer/use-composer-autocomplete.ts
3907
- var import_react14 = require("react");
3944
+ var import_react15 = require("react");
3908
3945
  function useComposerAutocomplete(options) {
3909
3946
  const { value, sources, acceptOnTab = true } = options;
3910
- const latest = (0, import_react14.useRef)(options);
3947
+ const latest = (0, import_react15.useRef)(options);
3911
3948
  latest.current = options;
3912
- const inputRef = (0, import_react14.useRef)(null);
3913
- const [caret, setCaret] = (0, import_react14.useState)(value.length);
3914
- const [items, setItems] = (0, import_react14.useState)([]);
3915
- const [isLoading, setLoading] = (0, import_react14.useState)(false);
3916
- const [error, setError] = (0, import_react14.useState)(null);
3917
- const [activeIndex, setActiveIndex] = (0, import_react14.useState)(0);
3918
- const [dismissedIndex, setDismissedIndex] = (0, import_react14.useState)(null);
3949
+ const inputRef = (0, import_react15.useRef)(null);
3950
+ const [caret, setCaret] = (0, import_react15.useState)(value.length);
3951
+ const [items, setItems] = (0, import_react15.useState)([]);
3952
+ const [isLoading, setLoading] = (0, import_react15.useState)(false);
3953
+ const [error, setError] = (0, import_react15.useState)(null);
3954
+ const [activeIndex, setActiveIndex] = (0, import_react15.useState)(0);
3955
+ const [dismissedIndex, setDismissedIndex] = (0, import_react15.useState)(null);
3919
3956
  const safeCaret = Math.min(caret, value.length);
3920
- const match = (0, import_react14.useMemo)(() => findActiveTrigger(value, safeCaret, sources), [
3957
+ const match = (0, import_react15.useMemo)(() => findActiveTrigger(value, safeCaret, sources), [
3921
3958
  value,
3922
3959
  safeCaret,
3923
3960
  sources
3924
3961
  ]);
3925
3962
  const isActive = match !== null && dismissedIndex !== match.index;
3926
- const matchRef = (0, import_react14.useRef)(match);
3963
+ const matchRef = (0, import_react15.useRef)(match);
3927
3964
  matchRef.current = match;
3928
- const caretRef = (0, import_react14.useRef)(safeCaret);
3965
+ const caretRef = (0, import_react15.useRef)(safeCaret);
3929
3966
  caretRef.current = safeCaret;
3930
- const itemsRef = (0, import_react14.useRef)(items);
3967
+ const itemsRef = (0, import_react15.useRef)(items);
3931
3968
  itemsRef.current = items;
3932
- const activeIndexRef = (0, import_react14.useRef)(activeIndex);
3969
+ const activeIndexRef = (0, import_react15.useRef)(activeIndex);
3933
3970
  activeIndexRef.current = activeIndex;
3934
3971
  const requestKey = isActive && match ? `${match.source.id}\0${match.query}` : null;
3935
- (0, import_react14.useEffect)(() => {
3972
+ (0, import_react15.useEffect)(() => {
3936
3973
  const current = matchRef.current;
3937
3974
  if (requestKey === null || current === null) {
3938
3975
  setItems([]);
@@ -3980,25 +4017,25 @@ function useComposerAutocomplete(options) {
3980
4017
  ]);
3981
4018
  const isOpen = isActive;
3982
4019
  const activeItem = isOpen ? items[activeIndex] ?? null : null;
3983
- const reactId = (0, import_react14.useId)();
4020
+ const reactId = (0, import_react15.useId)();
3984
4021
  const listboxId = options.id ?? `agent-autocomplete-${reactId}`;
3985
- const optionId = (0, import_react14.useCallback)((index) => `${listboxId}-option-${index}`, [
4022
+ const optionId = (0, import_react15.useCallback)((index) => `${listboxId}-option-${index}`, [
3986
4023
  listboxId
3987
4024
  ]);
3988
- const highlight = (0, import_react14.useCallback)((index) => {
4025
+ const highlight = (0, import_react15.useCallback)((index) => {
3989
4026
  const total = itemsRef.current.length;
3990
4027
  if (total === 0) return;
3991
4028
  setActiveIndex((index % total + total) % total);
3992
4029
  }, []);
3993
- const moveHighlight = (0, import_react14.useCallback)((delta) => highlight(activeIndexRef.current + delta), [
4030
+ const moveHighlight = (0, import_react15.useCallback)((delta) => highlight(activeIndexRef.current + delta), [
3994
4031
  highlight
3995
4032
  ]);
3996
- const dismiss = (0, import_react14.useCallback)(() => {
4033
+ const dismiss = (0, import_react15.useCallback)(() => {
3997
4034
  const current = matchRef.current;
3998
4035
  if (current) setDismissedIndex(current.index);
3999
4036
  }, []);
4000
- const pendingCaret = (0, import_react14.useRef)(null);
4001
- const accept = (0, import_react14.useCallback)((item) => {
4037
+ const pendingCaret = (0, import_react15.useRef)(null);
4038
+ const accept = (0, import_react15.useCallback)((item) => {
4002
4039
  const current = matchRef.current;
4003
4040
  if (!current) return;
4004
4041
  const chosen = item ?? itemsRef.current[activeIndexRef.current];
@@ -4009,16 +4046,16 @@ function useComposerAutocomplete(options) {
4009
4046
  setDismissedIndex(null);
4010
4047
  pendingCaret.current = edit.caret;
4011
4048
  }, []);
4012
- (0, import_react14.useLayoutEffect)(() => {
4049
+ (0, import_react15.useLayoutEffect)(() => {
4013
4050
  const position = pendingCaret.current;
4014
4051
  if (position === null) return;
4015
4052
  pendingCaret.current = null;
4016
4053
  inputRef.current?.setSelectionRange(position, position);
4017
4054
  });
4018
- const readCaret = (0, import_react14.useCallback)((element) => {
4055
+ const readCaret = (0, import_react15.useCallback)((element) => {
4019
4056
  setCaret(element.selectionStart ?? element.value.length);
4020
4057
  }, []);
4021
- const onKeyDown = (0, import_react14.useCallback)((event) => {
4058
+ const onKeyDown = (0, import_react15.useCallback)((event) => {
4022
4059
  if (!isOpen) return;
4023
4060
  const hasItems = itemsRef.current.length > 0;
4024
4061
  switch (event.key) {
@@ -4056,23 +4093,23 @@ function useComposerAutocomplete(options) {
4056
4093
  dismiss,
4057
4094
  moveHighlight
4058
4095
  ]);
4059
- const onChange = (0, import_react14.useCallback)((event) => {
4096
+ const onChange = (0, import_react15.useCallback)((event) => {
4060
4097
  readCaret(event.target);
4061
4098
  const next = findActiveTrigger(event.target.value, event.target.selectionStart ?? event.target.value.length, latest.current.sources);
4062
4099
  setDismissedIndex((current) => current !== null && next?.index === current ? current : null);
4063
4100
  }, [
4064
4101
  readCaret
4065
4102
  ]);
4066
- const onSelect = (0, import_react14.useCallback)((event) => readCaret(event.currentTarget), [
4103
+ const onSelect = (0, import_react15.useCallback)((event) => readCaret(event.currentTarget), [
4067
4104
  readCaret
4068
4105
  ]);
4069
- const onClick = (0, import_react14.useCallback)((event) => readCaret(event.currentTarget), [
4106
+ const onClick = (0, import_react15.useCallback)((event) => readCaret(event.currentTarget), [
4070
4107
  readCaret
4071
4108
  ]);
4072
- const setInput = (0, import_react14.useCallback)((element) => {
4109
+ const setInput = (0, import_react15.useCallback)((element) => {
4073
4110
  inputRef.current = element;
4074
4111
  }, []);
4075
- const getInputProps = (0, import_react14.useCallback)(() => ({
4112
+ const getInputProps = (0, import_react15.useCallback)(() => ({
4076
4113
  ref: setInput,
4077
4114
  onChange,
4078
4115
  onKeyDown,
@@ -4100,7 +4137,7 @@ function useComposerAutocomplete(options) {
4100
4137
  activeIndex,
4101
4138
  optionId
4102
4139
  ]);
4103
- const getListboxProps = (0, import_react14.useCallback)(() => ({
4140
+ const getListboxProps = (0, import_react15.useCallback)(() => ({
4104
4141
  id: listboxId,
4105
4142
  role: "listbox",
4106
4143
  "aria-label": match?.source.label ?? match?.source.id ?? "Suggestions"
@@ -4108,7 +4145,7 @@ function useComposerAutocomplete(options) {
4108
4145
  listboxId,
4109
4146
  match
4110
4147
  ]);
4111
- const getOptionProps = (0, import_react14.useCallback)((index) => ({
4148
+ const getOptionProps = (0, import_react15.useCallback)((index) => ({
4112
4149
  id: optionId(index),
4113
4150
  role: "option",
4114
4151
  "aria-selected": index === activeIndex
@@ -4142,7 +4179,7 @@ function isPromise(value) {
4142
4179
  __name(isPromise, "isPromise");
4143
4180
 
4144
4181
  // src/presentation/use-tool-catalog.ts
4145
- var import_react15 = require("react");
4182
+ var import_react16 = require("react");
4146
4183
  var shared = /* @__PURE__ */ new WeakMap();
4147
4184
  function load(client, agent) {
4148
4185
  let byAgent = shared.get(client);
@@ -4166,11 +4203,11 @@ function load(client, agent) {
4166
4203
  __name(load, "load");
4167
4204
  function useToolCatalog(options) {
4168
4205
  const { client, agent, enabled = true } = options;
4169
- const [entries, setEntries] = (0, import_react15.useState)([]);
4170
- const [isLoading, setLoading] = (0, import_react15.useState)(enabled);
4171
- const [error, setError] = (0, import_react15.useState)(null);
4172
- const [generation, setGeneration] = (0, import_react15.useState)(0);
4173
- (0, import_react15.useEffect)(() => {
4206
+ const [entries, setEntries] = (0, import_react16.useState)([]);
4207
+ const [isLoading, setLoading] = (0, import_react16.useState)(enabled);
4208
+ const [error, setError] = (0, import_react16.useState)(null);
4209
+ const [generation, setGeneration] = (0, import_react16.useState)(0);
4210
+ (0, import_react16.useEffect)(() => {
4174
4211
  if (!enabled) {
4175
4212
  setLoading(false);
4176
4213
  return;
@@ -4196,14 +4233,14 @@ function useToolCatalog(options) {
4196
4233
  enabled,
4197
4234
  generation
4198
4235
  ]);
4199
- const refresh = (0, import_react15.useCallback)(() => {
4236
+ const refresh = (0, import_react16.useCallback)(() => {
4200
4237
  shared.get(client)?.delete(agent ?? "");
4201
4238
  setGeneration((current) => current + 1);
4202
4239
  }, [
4203
4240
  client,
4204
4241
  agent
4205
4242
  ]);
4206
- const catalog = (0, import_react15.useMemo)(() => toolCatalogFrom(entries), [
4243
+ const catalog = (0, import_react16.useMemo)(() => toolCatalogFrom(entries), [
4207
4244
  entries
4208
4245
  ]);
4209
4246
  return {
@@ -4217,7 +4254,7 @@ function useToolCatalog(options) {
4217
4254
  __name(useToolCatalog, "useToolCatalog");
4218
4255
 
4219
4256
  // src/approvals/countdown.ts
4220
- var import_react16 = require("react");
4257
+ var import_react17 = require("react");
4221
4258
  function approvalCountdown(expiresAt, now = Date.now()) {
4222
4259
  const deadline = expiresAt == null ? Number.NaN : Date.parse(expiresAt);
4223
4260
  if (!Number.isFinite(deadline)) {
@@ -4235,10 +4272,10 @@ function approvalCountdown(expiresAt, now = Date.now()) {
4235
4272
  __name(approvalCountdown, "approvalCountdown");
4236
4273
  function useApprovalCountdown(expiresAt, options = {}) {
4237
4274
  const { intervalMs = 1e3 } = options;
4238
- const nowRef = (0, import_react16.useRef)(options.now ?? Date.now);
4275
+ const nowRef = (0, import_react17.useRef)(options.now ?? Date.now);
4239
4276
  nowRef.current = options.now ?? Date.now;
4240
- const [state, setState] = (0, import_react16.useState)(() => approvalCountdown(expiresAt, nowRef.current()));
4241
- (0, import_react16.useEffect)(() => {
4277
+ const [state, setState] = (0, import_react17.useState)(() => approvalCountdown(expiresAt, nowRef.current()));
4278
+ (0, import_react17.useEffect)(() => {
4242
4279
  const read = /* @__PURE__ */ __name(() => approvalCountdown(expiresAt, nowRef.current()), "read");
4243
4280
  const first = read();
4244
4281
  setState(first);
@@ -4485,21 +4522,21 @@ function sumUsage(rows) {
4485
4522
  __name(sumUsage, "sumUsage");
4486
4523
 
4487
4524
  // src/use-agent-chat.ts
4488
- var import_react17 = require("@ai-sdk/react");
4489
- var import_react18 = require("react");
4525
+ var import_react18 = require("@ai-sdk/react");
4526
+ var import_react19 = require("react");
4490
4527
  function useAgentChat(options) {
4491
- const latest = (0, import_react18.useRef)(options);
4528
+ const latest = (0, import_react19.useRef)(options);
4492
4529
  latest.current = options;
4493
- const [runId, setRunId] = (0, import_react18.useState)(options.resumeRunId);
4494
- const runIdRef = (0, import_react18.useRef)(runId);
4530
+ const [runId, setRunId] = (0, import_react19.useState)(options.resumeRunId);
4531
+ const runIdRef = (0, import_react19.useRef)(runId);
4495
4532
  runIdRef.current = runId;
4496
- const settlingRunIdRef = (0, import_react18.useRef)(void 0);
4497
- const autoResumeRunIdRef = (0, import_react18.useRef)(void 0);
4498
- const [autoResume, setAutoResume] = (0, import_react18.useState)(false);
4499
- const [activeRunId, setActiveRunId] = (0, import_react18.useState)(null);
4500
- const regenerateNext = (0, import_react18.useRef)(false);
4501
- const createdThreadId = (0, import_react18.useRef)(void 0);
4502
- const client = (0, import_react18.useMemo)(() => {
4533
+ const settlingRunIdRef = (0, import_react19.useRef)(void 0);
4534
+ const autoResumeRunIdRef = (0, import_react19.useRef)(void 0);
4535
+ const [autoResume, setAutoResume] = (0, import_react19.useState)(false);
4536
+ const [activeRunId, setActiveRunId] = (0, import_react19.useState)(null);
4537
+ const regenerateNext = (0, import_react19.useRef)(false);
4538
+ const createdThreadId = (0, import_react19.useRef)(void 0);
4539
+ const client = (0, import_react19.useMemo)(() => {
4503
4540
  if (options.backend) return options.backend;
4504
4541
  if (options.client) return options.client;
4505
4542
  return new AgentClient({
@@ -4512,14 +4549,17 @@ function useAgentChat(options) {
4512
4549
  ...options.fetch !== void 0 ? {
4513
4550
  fetch: options.fetch
4514
4551
  } : {},
4552
+ ...options.attachments !== void 0 ? {
4553
+ attachments: options.attachments
4554
+ } : {},
4515
4555
  getHeaders: /* @__PURE__ */ __name(async () => mergeHeaders(latest.current), "getHeaders")
4516
4556
  });
4517
4557
  }, []);
4518
- const [connection, setConnection] = (0, import_react18.useState)({
4558
+ const [connection, setConnection] = (0, import_react19.useState)({
4519
4559
  status: "live"
4520
4560
  });
4521
- const resyncAfterSettle = (0, import_react18.useRef)(false);
4522
- (0, import_react18.useEffect)(() => {
4561
+ const resyncAfterSettle = (0, import_react19.useRef)(false);
4562
+ (0, import_react19.useEffect)(() => {
4523
4563
  if (!options.resume || options.threadId === void 0) return;
4524
4564
  let cancelled = false;
4525
4565
  const threadId = options.threadId;
@@ -4539,7 +4579,7 @@ function useAgentChat(options) {
4539
4579
  options.resume,
4540
4580
  options.threadId
4541
4581
  ]);
4542
- const transport = (0, import_react18.useMemo)(() => {
4582
+ const transport = (0, import_react19.useMemo)(() => {
4543
4583
  function onMeta(meta) {
4544
4584
  settlingRunIdRef.current = meta.runId;
4545
4585
  setRunId(meta.runId);
@@ -4594,8 +4634,8 @@ function useAgentChat(options) {
4594
4634
  }, "onAttemptStart")
4595
4635
  });
4596
4636
  }, []);
4597
- const backgroundRef = (0, import_react18.useRef)(() => Promise.resolve());
4598
- const chat = (0, import_react17.useChat)({
4637
+ const backgroundRef = (0, import_react19.useRef)(() => Promise.resolve());
4638
+ const chat = (0, import_react18.useChat)({
4599
4639
  transport,
4600
4640
  resume: options.resumeRunId !== void 0 || autoResume,
4601
4641
  ...options.threadId !== void 0 ? {
@@ -4643,7 +4683,7 @@ function useAgentChat(options) {
4643
4683
  }
4644
4684
  }, "onFinish")
4645
4685
  });
4646
- const chatRef = (0, import_react18.useRef)(chat);
4686
+ const chatRef = (0, import_react19.useRef)(chat);
4647
4687
  chatRef.current = chat;
4648
4688
  async function resyncFromThread() {
4649
4689
  const threadId = latest.current.threadId ?? createdThreadId.current;
@@ -4655,11 +4695,11 @@ function useAgentChat(options) {
4655
4695
  }
4656
4696
  }
4657
4697
  __name(resyncFromThread, "resyncFromThread");
4658
- const turnInFlight = (0, import_react18.useRef)(false);
4659
- const isTurnInFlight = (0, import_react18.useCallback)(() => turnInFlight.current || transport.isAttemptLive, [
4698
+ const turnInFlight = (0, import_react19.useRef)(false);
4699
+ const isTurnInFlight = (0, import_react19.useCallback)(() => turnInFlight.current || transport.isAttemptLive, [
4660
4700
  transport
4661
4701
  ]);
4662
- const sendMessage = (0, import_react18.useCallback)(async (...args) => {
4702
+ const sendMessage = (0, import_react19.useCallback)(async (...args) => {
4663
4703
  const blocked = latest.current.blocked;
4664
4704
  if (blocked != null) throw new QuotaBlockedError(blocked);
4665
4705
  if (isTurnInFlight()) return;
@@ -4672,15 +4712,15 @@ function useAgentChat(options) {
4672
4712
  }, [
4673
4713
  isTurnInFlight
4674
4714
  ]);
4675
- const addToolResult = (0, import_react18.useCallback)(({ tool, toolCallId, output }) => chatRef.current.addToolResult({
4715
+ const addToolResult = (0, import_react19.useCallback)(({ tool, toolCallId, output }) => chatRef.current.addToolResult({
4676
4716
  tool,
4677
4717
  toolCallId,
4678
4718
  output
4679
4719
  }), []);
4680
- const [threads, setThreads] = (0, import_react18.useState)([]);
4681
- const [quota, setQuota] = (0, import_react18.useState)(null);
4682
- const [backgroundRuns, setBackgroundRuns] = (0, import_react18.useState)([]);
4683
- const refreshBackground = (0, import_react18.useCallback)(async () => {
4720
+ const [threads, setThreads] = (0, import_react19.useState)([]);
4721
+ const [quota, setQuota] = (0, import_react19.useState)(null);
4722
+ const [backgroundRuns, setBackgroundRuns] = (0, import_react19.useState)([]);
4723
+ const refreshBackground = (0, import_react19.useCallback)(async () => {
4684
4724
  const threadId = latest.current.threadId ?? createdThreadId.current;
4685
4725
  if (threadId === void 0) {
4686
4726
  return;
@@ -4705,7 +4745,7 @@ function useAgentChat(options) {
4705
4745
  ]);
4706
4746
  backgroundRef.current = refreshBackground;
4707
4747
  const isWorking = backgroundRuns.some((run) => run.status === "running");
4708
- (0, import_react18.useEffect)(() => {
4748
+ (0, import_react19.useEffect)(() => {
4709
4749
  if (options.background !== true || options.threadId === void 0) {
4710
4750
  return;
4711
4751
  }
@@ -4715,7 +4755,7 @@ function useAgentChat(options) {
4715
4755
  options.threadId,
4716
4756
  refreshBackground
4717
4757
  ]);
4718
- (0, import_react18.useEffect)(() => {
4758
+ (0, import_react19.useEffect)(() => {
4719
4759
  const every = latest.current.backgroundPollMs ?? 5e3;
4720
4760
  if (latest.current.background !== true || !isWorking || every <= 0) {
4721
4761
  return;
@@ -4726,26 +4766,26 @@ function useAgentChat(options) {
4726
4766
  isWorking,
4727
4767
  refreshBackground
4728
4768
  ]);
4729
- const loadThreads = (0, import_react18.useCallback)(async () => {
4769
+ const loadThreads = (0, import_react19.useCallback)(async () => {
4730
4770
  const list = await client.listThreads();
4731
4771
  setThreads(list);
4732
4772
  return list;
4733
4773
  }, [
4734
4774
  client
4735
4775
  ]);
4736
- const loadThread = (0, import_react18.useCallback)((id) => client.getThread(id), [
4776
+ const loadThread = (0, import_react19.useCallback)((id) => client.getThread(id), [
4737
4777
  client
4738
4778
  ]);
4739
- const deleteThread = (0, import_react18.useCallback)(async (id) => {
4779
+ const deleteThread = (0, import_react19.useCallback)(async (id) => {
4740
4780
  await client.deleteThread(id);
4741
4781
  setThreads((current) => current.filter((thread) => thread.id !== id));
4742
4782
  }, [
4743
4783
  client
4744
4784
  ]);
4745
- const forkThread = (0, import_react18.useCallback)((threadId, messageId) => requireBackendMethod(client, "forkFromMessage")(threadId, messageId), [
4785
+ const forkThread = (0, import_react19.useCallback)((threadId, messageId) => requireBackendMethod(client, "forkFromMessage")(threadId, messageId), [
4746
4786
  client
4747
4787
  ]);
4748
- const renameThread = (0, import_react18.useCallback)(async (id, title) => {
4788
+ const renameThread = (0, import_react19.useCallback)(async (id, title) => {
4749
4789
  await client.updateThread(id, {
4750
4790
  title
4751
4791
  });
@@ -4756,24 +4796,24 @@ function useAgentChat(options) {
4756
4796
  }, [
4757
4797
  client
4758
4798
  ]);
4759
- const promoteThread = (0, import_react18.useCallback)(async (id) => {
4799
+ const promoteThread = (0, import_react19.useCallback)(async (id) => {
4760
4800
  await requireBackendMethod(client, "promoteThread")(id);
4761
4801
  await loadThreads();
4762
4802
  }, [
4763
4803
  client,
4764
4804
  loadThreads
4765
4805
  ]);
4766
- const truncateFromMessage = (0, import_react18.useCallback)((threadId, messageId) => requireBackendMethod(client, "truncateFromMessage")(threadId, messageId).then(() => void 0), [
4806
+ const truncateFromMessage = (0, import_react19.useCallback)((threadId, messageId) => requireBackendMethod(client, "truncateFromMessage")(threadId, messageId).then(() => void 0), [
4767
4807
  client
4768
4808
  ]);
4769
- const loadQuota = (0, import_react18.useCallback)(async () => {
4809
+ const loadQuota = (0, import_react19.useCallback)(async () => {
4770
4810
  const today = await requireBackendMethod(client, "getQuotaToday")();
4771
4811
  setQuota(today);
4772
4812
  return today;
4773
4813
  }, [
4774
4814
  client
4775
4815
  ]);
4776
- const cancel = (0, import_react18.useCallback)(async () => {
4816
+ const cancel = (0, import_react19.useCallback)(async () => {
4777
4817
  chatRef.current.stop();
4778
4818
  const activeRunId2 = runIdRef.current;
4779
4819
  if (activeRunId2) {
@@ -4785,7 +4825,7 @@ function useAgentChat(options) {
4785
4825
  }, [
4786
4826
  client
4787
4827
  ]);
4788
- const approve = (0, import_react18.useCallback)(async ({ toolCallId, remember, via }) => {
4828
+ const approve = (0, import_react19.useCallback)(async ({ toolCallId, remember, via }) => {
4789
4829
  await requireBackendMethod(client, "approveToolCall")({
4790
4830
  toolCallId,
4791
4831
  ...remember === true ? {
@@ -4798,7 +4838,7 @@ function useAgentChat(options) {
4798
4838
  }, [
4799
4839
  client
4800
4840
  ]);
4801
- const reject = (0, import_react18.useCallback)(async ({ toolCallId, reason, via }) => {
4841
+ const reject = (0, import_react19.useCallback)(async ({ toolCallId, reason, via }) => {
4802
4842
  await requireBackendMethod(client, "rejectToolCall")({
4803
4843
  toolCallId,
4804
4844
  ...reason !== void 0 ? {
@@ -4811,7 +4851,7 @@ function useAgentChat(options) {
4811
4851
  }, [
4812
4852
  client
4813
4853
  ]);
4814
- const answer = (0, import_react18.useCallback)(async ({ toolCallId, answers }) => {
4854
+ const answer = (0, import_react19.useCallback)(async ({ toolCallId, answers }) => {
4815
4855
  await requireBackendMethod(client, "answerToolCall")({
4816
4856
  toolCallId,
4817
4857
  ...answers !== void 0 ? {
@@ -4821,14 +4861,14 @@ function useAgentChat(options) {
4821
4861
  }, [
4822
4862
  client
4823
4863
  ]);
4824
- const skip = (0, import_react18.useCallback)(async ({ toolCallId }) => {
4864
+ const skip = (0, import_react19.useCallback)(async ({ toolCallId }) => {
4825
4865
  await requireBackendMethod(client, "skipToolCall")({
4826
4866
  toolCallId
4827
4867
  });
4828
4868
  }, [
4829
4869
  client
4830
4870
  ]);
4831
- const regenerate = (0, import_react18.useCallback)(() => {
4871
+ const regenerate = (0, import_react19.useCallback)(() => {
4832
4872
  const blocked = latest.current.blocked;
4833
4873
  if (blocked != null) throw new QuotaBlockedError(blocked);
4834
4874
  if (isTurnInFlight()) return;
@@ -4845,7 +4885,7 @@ function useAgentChat(options) {
4845
4885
  isWorking,
4846
4886
  refresh: refreshBackground
4847
4887
  };
4848
- const setThreadModel = (0, import_react18.useCallback)(async (model) => {
4888
+ const setThreadModel = (0, import_react19.useCallback)(async (model) => {
4849
4889
  const threadId = latest.current.threadId ?? createdThreadId.current;
4850
4890
  if (threadId === void 0) {
4851
4891
  throw new Error("setThreadModel: this chat has no thread yet");
@@ -4859,7 +4899,7 @@ function useAgentChat(options) {
4859
4899
  }, [
4860
4900
  client
4861
4901
  ]);
4862
- const getThreadId = (0, import_react18.useCallback)(() => latest.current.threadId ?? createdThreadId.current, []);
4902
+ const getThreadId = (0, import_react19.useCallback)(() => latest.current.threadId ?? createdThreadId.current, []);
4863
4903
  const status = connection.status === "reconnecting" ? "reconnecting" : chat.status;
4864
4904
  return {
4865
4905
  ...chat,
@@ -4926,6 +4966,7 @@ __name(mergeHeaders, "mergeHeaders");
4926
4966
  AgentChatTransport,
4927
4967
  AgentClient,
4928
4968
  AgentHttpError,
4969
+ AmbientRenderUiContext,
4929
4970
  ChatInput,
4930
4971
  DEFAULT_SPEECH_LANG,
4931
4972
  MessageItem,
@@ -4972,6 +5013,7 @@ __name(mergeHeaders, "mergeHeaders");
4972
5013
  toolCatalogFrom,
4973
5014
  useAgentChat,
4974
5015
  useAgents,
5016
+ useAmbientRenderUi,
4975
5017
  useApprovalCountdown,
4976
5018
  useAttachments,
4977
5019
  useChatTranscript,