@dudousxd/nestjs-agent-react 0.31.4 → 0.32.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.js CHANGED
@@ -527,6 +527,7 @@ var AgentChatTransport = class {
527
527
  const message = lastMessage ? extractText(lastMessage) : "";
528
528
  const body = {
529
529
  ...this.options.agent !== void 0 ? { agent: this.options.agent } : {},
530
+ ...this.options.persona !== void 0 ? { persona: this.options.persona } : {},
530
531
  ...this.options.getBody?.() ?? {},
531
532
  ...options.body ?? {},
532
533
  message
@@ -2155,7 +2156,7 @@ function applyPatch(target, patch) {
2155
2156
  }
2156
2157
 
2157
2158
  // src/catalog/use-agents.ts
2158
- import { useMemo as useMemo5 } from "react";
2159
+ import { useCallback as useCallback4, useMemo as useMemo5 } from "react";
2159
2160
 
2160
2161
  // src/catalog/use-resource.ts
2161
2162
  import { useCallback as useCallback3, useEffect as useEffect5, useRef as useRef4, useState as useState5 } from "react";
@@ -2197,16 +2198,24 @@ function useAgents(options = {}) {
2197
2198
  "",
2198
2199
  enabled
2199
2200
  );
2201
+ const find = useCallback4(
2202
+ (name) => (data ?? []).find(
2203
+ (agent) => name === void 0 ? agent.isDefault === true : agent.name === name
2204
+ ),
2205
+ [data]
2206
+ );
2200
2207
  return useMemo5(() => {
2201
2208
  const agents = data ?? [];
2202
2209
  return {
2203
2210
  agents,
2204
2211
  defaultAgent: agents.find((agent) => agent.isDefault === true)?.name ?? null,
2212
+ personasOf: (agent) => find(agent)?.personas ?? [],
2213
+ defaultPersonaOf: (agent) => find(agent)?.defaultPersona ?? null,
2205
2214
  isLoading,
2206
2215
  error,
2207
2216
  refresh
2208
2217
  };
2209
- }, [data, isLoading, error, refresh]);
2218
+ }, [data, find, isLoading, error, refresh]);
2210
2219
  }
2211
2220
 
2212
2221
  // src/catalog/use-models.ts
@@ -2304,7 +2313,7 @@ function useQuota(options = {}) {
2304
2313
  }
2305
2314
 
2306
2315
  // src/feedback/use-message-feedback.ts
2307
- import { useCallback as useCallback4, useRef as useRef5, useState as useState6 } from "react";
2316
+ import { useCallback as useCallback5, useRef as useRef5, useState as useState6 } from "react";
2308
2317
  function useMessageFeedback(options = {}) {
2309
2318
  const backend = useAgentBackend(options.backend);
2310
2319
  const latest = useRef5({ ...options, backend });
@@ -2315,7 +2324,7 @@ function useMessageFeedback(options = {}) {
2315
2324
  const localRef = useRef5(local);
2316
2325
  localRef.current = local;
2317
2326
  const resolved = useRef5(/* @__PURE__ */ new Map());
2318
- const feedbackOf = useCallback4(
2327
+ const feedbackOf = useCallback5(
2319
2328
  (message) => {
2320
2329
  const mine = local.get(message.id);
2321
2330
  if (mine !== void 0) return mine.feedback;
@@ -2323,8 +2332,8 @@ function useMessageFeedback(options = {}) {
2323
2332
  },
2324
2333
  [local]
2325
2334
  );
2326
- const isPending = useCallback4((message) => pending.has(message.id), [pending]);
2327
- const storedIdFor = useCallback4(async (message) => {
2335
+ const isPending = useCallback5((message) => pending.has(message.id), [pending]);
2336
+ const storedIdFor = useCallback5(async (message) => {
2328
2337
  const runId = metadataOf(message).runId;
2329
2338
  if (runId === void 0) return message.id;
2330
2339
  const known = resolved.current.get(message.id);
@@ -2342,7 +2351,7 @@ function useMessageFeedback(options = {}) {
2342
2351
  resolved.current.set(message.id, row.id);
2343
2352
  return row.id;
2344
2353
  }, []);
2345
- const rate = useCallback4(
2354
+ const rate = useCallback5(
2346
2355
  async (message, value, comment) => {
2347
2356
  const setFeedback = requireBackendMethod(latest.current.backend, "setMessageFeedback");
2348
2357
  const had = localRef.current.get(message.id);
@@ -2381,7 +2390,7 @@ function useMessageFeedback(options = {}) {
2381
2390
  },
2382
2391
  [storedIdFor]
2383
2392
  );
2384
- const toggle = useCallback4(
2393
+ const toggle = useCallback5(
2385
2394
  (message, value) => {
2386
2395
  const mine = localRef.current.get(message.id);
2387
2396
  const current = mine !== void 0 ? mine.feedback : metadataOf(message).feedback ?? null;
@@ -2397,7 +2406,7 @@ function metadataOf(message) {
2397
2406
  }
2398
2407
 
2399
2408
  // src/threads/use-threads.ts
2400
- import { useCallback as useCallback5, useEffect as useEffect7, useRef as useRef6, useState as useState7 } from "react";
2409
+ import { useCallback as useCallback6, useEffect as useEffect7, useRef as useRef6, useState as useState7 } from "react";
2401
2410
  function useThreads(options = {}) {
2402
2411
  const { enabled = true } = options;
2403
2412
  const backend = useAgentBackend(options.backend);
@@ -2407,7 +2416,7 @@ function useThreads(options = {}) {
2407
2416
  const threadsRef = useRef6(threads);
2408
2417
  threadsRef.current = threads;
2409
2418
  const generation = useRef6(0);
2410
- const refresh = useCallback5(async () => {
2419
+ const refresh = useCallback6(async () => {
2411
2420
  const mine = ++generation.current;
2412
2421
  setIsLoading(true);
2413
2422
  try {
@@ -2439,7 +2448,7 @@ function useThreads(options = {}) {
2439
2448
  }
2440
2449
  });
2441
2450
  }, [backend, enabled, refresh]);
2442
- const rename = useCallback5(
2451
+ const rename = useCallback6(
2443
2452
  async (id, title) => {
2444
2453
  const before = threadsRef.current;
2445
2454
  setThreads(
@@ -2455,7 +2464,7 @@ function useThreads(options = {}) {
2455
2464
  },
2456
2465
  [backend]
2457
2466
  );
2458
- const remove = useCallback5(
2467
+ const remove = useCallback6(
2459
2468
  async (id) => {
2460
2469
  const before = threadsRef.current;
2461
2470
  setThreads((current) => current.filter((thread) => thread.id !== id));
@@ -2514,7 +2523,7 @@ function backgroundRunsFromThread(messages) {
2514
2523
  import { useEffect as useEffect9, useState as useState9 } from "react";
2515
2524
 
2516
2525
  // src/components/use-speech-recognition.ts
2517
- import { useCallback as useCallback6, useEffect as useEffect8, useMemo as useMemo8, useRef as useRef7, useState as useState8 } from "react";
2526
+ import { useCallback as useCallback7, useEffect as useEffect8, useMemo as useMemo8, useRef as useRef7, useState as useState8 } from "react";
2518
2527
  function getRecognitionCtor() {
2519
2528
  if (typeof window === "undefined") return null;
2520
2529
  const scope = window;
@@ -2569,7 +2578,7 @@ function useSpeechRecognition({
2569
2578
  recognitionRef.current = null;
2570
2579
  };
2571
2580
  }, [ctor, lang]);
2572
- const start = useCallback6(() => {
2581
+ const start = useCallback7(() => {
2573
2582
  const recognition = recognitionRef.current;
2574
2583
  if (!recognition) return;
2575
2584
  try {
@@ -2579,7 +2588,7 @@ function useSpeechRecognition({
2579
2588
  console.warn("SpeechRecognition start failed", error);
2580
2589
  }
2581
2590
  }, []);
2582
- const stop = useCallback6(() => {
2591
+ const stop = useCallback7(() => {
2583
2592
  const recognition = recognitionRef.current;
2584
2593
  if (!recognition) return;
2585
2594
  try {
@@ -2699,7 +2708,7 @@ function ChatInput({
2699
2708
  import React2 from "react";
2700
2709
 
2701
2710
  // src/transcript/use-chat-transcript.ts
2702
- import { useCallback as useCallback8, useEffect as useEffect11, useRef as useRef9, useState as useState11 } from "react";
2711
+ import { useCallback as useCallback9, useEffect as useEffect11, useRef as useRef9, useState as useState11 } from "react";
2703
2712
 
2704
2713
  // src/transcript/model.ts
2705
2714
  import {
@@ -3572,14 +3581,14 @@ function formatCostUsd(cost) {
3572
3581
  }
3573
3582
 
3574
3583
  // src/transcript/use-stick-to-bottom.ts
3575
- import { useCallback as useCallback7, useEffect as useEffect10, useRef as useRef8, useState as useState10 } from "react";
3584
+ import { useCallback as useCallback8, useEffect as useEffect10, useRef as useRef8, useState as useState10 } from "react";
3576
3585
  function useStickToBottom({
3577
3586
  contentKey,
3578
3587
  threshold = 32
3579
3588
  }) {
3580
3589
  const containerRef = useRef8(null);
3581
3590
  const [isAtBottom, setIsAtBottom] = useState10(true);
3582
- const measure = useCallback7(() => {
3591
+ const measure = useCallback8(() => {
3583
3592
  const element = containerRef.current;
3584
3593
  if (!element) {
3585
3594
  return;
@@ -3587,7 +3596,7 @@ function useStickToBottom({
3587
3596
  const distance = element.scrollHeight - element.scrollTop - element.clientHeight;
3588
3597
  setIsAtBottom(distance <= threshold);
3589
3598
  }, [threshold]);
3590
- const scrollToBottom = useCallback7(() => {
3599
+ const scrollToBottom = useCallback8(() => {
3591
3600
  const element = containerRef.current;
3592
3601
  if (!element) {
3593
3602
  return;
@@ -3595,7 +3604,7 @@ function useStickToBottom({
3595
3604
  element.scrollTop = element.scrollHeight;
3596
3605
  setIsAtBottom(true);
3597
3606
  }, []);
3598
- const setContainer = useCallback7(
3607
+ const setContainer = useCallback8(
3599
3608
  (element) => {
3600
3609
  containerRef.current = element;
3601
3610
  if (element) {
@@ -3609,7 +3618,7 @@ function useStickToBottom({
3609
3618
  scrollToBottom();
3610
3619
  }
3611
3620
  }, [contentKey, isAtBottom, scrollToBottom]);
3612
- const getContainerProps = useCallback7(
3621
+ const getContainerProps = useCallback8(
3613
3622
  () => ({ ref: setContainer, onScroll: measure }),
3614
3623
  [setContainer, measure]
3615
3624
  );
@@ -3656,7 +3665,7 @@ function useChatTranscript(options) {
3656
3665
  streamingMessageId,
3657
3666
  options
3658
3667
  });
3659
- const stop = useCallback8(() => {
3668
+ const stop = useCallback9(() => {
3660
3669
  const current = latest.current;
3661
3670
  if (current.status !== "submitted" && current.status !== "streaming" && current.status !== "reconnecting") {
3662
3671
  return;
@@ -3664,13 +3673,13 @@ function useChatTranscript(options) {
3664
3673
  setStopRequested(true);
3665
3674
  void current.onStop?.();
3666
3675
  }, []);
3667
- const loadEarlier = useCallback8(
3676
+ const loadEarlier = useCallback9(
3668
3677
  () => setVisibleCount(
3669
3678
  (count) => count + (latest.current.loadEarlierStep ?? DEFAULT_LOAD_EARLIER_STEP)
3670
3679
  ),
3671
3680
  []
3672
3681
  );
3673
- const showAll = useCallback8(() => setVisibleCount(latest.current.messages.length), []);
3682
+ const showAll = useCallback9(() => setVisibleCount(latest.current.messages.length), []);
3674
3683
  const scroll = useStickToBottom({
3675
3684
  contentKey: contentSignature(messages),
3676
3685
  ...stickToBottomThreshold !== void 0 ? { threshold: stickToBottomThreshold } : {}
@@ -3708,7 +3717,7 @@ function useQueuedItems(queue, readOnly) {
3708
3717
  const latestQueue = useRef9(queue);
3709
3718
  latestQueue.current = queue;
3710
3719
  const removers = useRef9(/* @__PURE__ */ new Map());
3711
- const removerFor = useCallback8((id) => {
3720
+ const removerFor = useCallback9((id) => {
3712
3721
  let remover = removers.current.get(id);
3713
3722
  if (remover === void 0) {
3714
3723
  remover = () => {
@@ -3784,14 +3793,14 @@ function useTranscriptItems({
3784
3793
  );
3785
3794
  const callbackCache = useRef9(/* @__PURE__ */ new Map());
3786
3795
  const reasoningToggleCache = useRef9(/* @__PURE__ */ new Map());
3787
- const toggleReasoning = useCallback8((key, open) => {
3796
+ const toggleReasoning = useCallback9((key, open) => {
3788
3797
  setOpenReasoning((current) => {
3789
3798
  const next = new Map(current);
3790
3799
  next.set(key, open ?? !(current.get(key) ?? false));
3791
3800
  return next;
3792
3801
  });
3793
3802
  }, []);
3794
- const stableToggle = useCallback8(
3803
+ const stableToggle = useCallback9(
3795
3804
  (key) => {
3796
3805
  let cached = reasoningToggleCache.current.get(key);
3797
3806
  if (!cached) {
@@ -3802,10 +3811,10 @@ function useTranscriptItems({
3802
3811
  },
3803
3812
  [toggleReasoning]
3804
3813
  );
3805
- const pick = useCallback8((toolCallId, questionId, values) => {
3814
+ const pick = useCallback9((toolCallId, questionId, values) => {
3806
3815
  setPicks((current) => new Map(current).set(pickKey(toolCallId, questionId), values));
3807
3816
  }, []);
3808
- const settle = useCallback8(
3817
+ const settle = useCallback9(
3809
3818
  (toolCallId, action, send) => {
3810
3819
  setSettleErrors((current) => {
3811
3820
  if (!current.has(toolCallId)) {
@@ -3837,7 +3846,7 @@ function useTranscriptItems({
3837
3846
  },
3838
3847
  []
3839
3848
  );
3840
- const answer = useCallback8(
3849
+ const answer = useCallback9(
3841
3850
  (toolCallId) => {
3842
3851
  const current = latest.current;
3843
3852
  const onAnswer = current.handlers.onAnswer;
@@ -3852,7 +3861,7 @@ function useTranscriptItems({
3852
3861
  },
3853
3862
  [settle]
3854
3863
  );
3855
- const skip = useCallback8(
3864
+ const skip = useCallback9(
3856
3865
  (toolCallId) => {
3857
3866
  const onSkip = latest.current.handlers.onSkip;
3858
3867
  if (onSkip) {
@@ -3861,7 +3870,7 @@ function useTranscriptItems({
3861
3870
  },
3862
3871
  [settle]
3863
3872
  );
3864
- const approve = useCallback8(
3873
+ const approve = useCallback9(
3865
3874
  (toolCallId, options2) => {
3866
3875
  const onApprove = latest.current.handlers.onApprove;
3867
3876
  if (onApprove) {
@@ -3874,7 +3883,7 @@ function useTranscriptItems({
3874
3883
  },
3875
3884
  [settle]
3876
3885
  );
3877
- const reject = useCallback8(
3886
+ const reject = useCallback9(
3878
3887
  (toolCallId) => {
3879
3888
  const onReject = latest.current.handlers.onReject;
3880
3889
  if (onReject) {
@@ -3883,7 +3892,7 @@ function useTranscriptItems({
3883
3892
  },
3884
3893
  [settle]
3885
3894
  );
3886
- const callbacksFor = useCallback8((id) => {
3895
+ const callbacksFor = useCallback9((id) => {
3887
3896
  const cached = callbackCache.current.get(id);
3888
3897
  if (cached) {
3889
3898
  return cached;
@@ -4608,7 +4617,7 @@ function toItem(entry) {
4608
4617
  }
4609
4618
 
4610
4619
  // src/composer/use-composer-autocomplete.ts
4611
- import { useCallback as useCallback9, useEffect as useEffect12, useId, useLayoutEffect, useMemo as useMemo9, useRef as useRef10, useState as useState12 } from "react";
4620
+ import { useCallback as useCallback10, useEffect as useEffect12, useId, useLayoutEffect, useMemo as useMemo9, useRef as useRef10, useState as useState12 } from "react";
4612
4621
  function useComposerAutocomplete(options) {
4613
4622
  const { value, sources, acceptOnTab = true } = options;
4614
4623
  const latest = useRef10(options);
@@ -4683,22 +4692,22 @@ function useComposerAutocomplete(options) {
4683
4692
  const activeItem = isOpen ? items[activeIndex] ?? null : null;
4684
4693
  const reactId = useId();
4685
4694
  const listboxId = options.id ?? `agent-autocomplete-${reactId}`;
4686
- const optionId = useCallback9((index) => `${listboxId}-option-${index}`, [listboxId]);
4687
- const highlight = useCallback9((index) => {
4695
+ const optionId = useCallback10((index) => `${listboxId}-option-${index}`, [listboxId]);
4696
+ const highlight = useCallback10((index) => {
4688
4697
  const total = itemsRef.current.length;
4689
4698
  if (total === 0) return;
4690
4699
  setActiveIndex((index % total + total) % total);
4691
4700
  }, []);
4692
- const moveHighlight = useCallback9(
4701
+ const moveHighlight = useCallback10(
4693
4702
  (delta) => highlight(activeIndexRef.current + delta),
4694
4703
  [highlight]
4695
4704
  );
4696
- const dismiss = useCallback9(() => {
4705
+ const dismiss = useCallback10(() => {
4697
4706
  const current = matchRef.current;
4698
4707
  if (current) setDismissedIndex(current.index);
4699
4708
  }, []);
4700
4709
  const pendingCaret = useRef10(null);
4701
- const accept = useCallback9((item) => {
4710
+ const accept = useCallback10((item) => {
4702
4711
  const current = matchRef.current;
4703
4712
  if (!current) return;
4704
4713
  const chosen = item ?? itemsRef.current[activeIndexRef.current];
@@ -4715,10 +4724,10 @@ function useComposerAutocomplete(options) {
4715
4724
  pendingCaret.current = null;
4716
4725
  inputRef.current?.setSelectionRange(position, position);
4717
4726
  });
4718
- const readCaret = useCallback9((element) => {
4727
+ const readCaret = useCallback10((element) => {
4719
4728
  setCaret(element.selectionStart ?? element.value.length);
4720
4729
  }, []);
4721
- const onKeyDown = useCallback9(
4730
+ const onKeyDown = useCallback10(
4722
4731
  (event) => {
4723
4732
  if (!isOpen) return;
4724
4733
  const hasItems = itemsRef.current.length > 0;
@@ -4753,7 +4762,7 @@ function useComposerAutocomplete(options) {
4753
4762
  },
4754
4763
  [isOpen, acceptOnTab, accept, dismiss, moveHighlight]
4755
4764
  );
4756
- const onChange = useCallback9(
4765
+ const onChange = useCallback10(
4757
4766
  (event) => {
4758
4767
  readCaret(event.target);
4759
4768
  const next = findActiveTrigger(
@@ -4767,18 +4776,18 @@ function useComposerAutocomplete(options) {
4767
4776
  },
4768
4777
  [readCaret]
4769
4778
  );
4770
- const onSelect = useCallback9(
4779
+ const onSelect = useCallback10(
4771
4780
  (event) => readCaret(event.currentTarget),
4772
4781
  [readCaret]
4773
4782
  );
4774
- const onClick = useCallback9(
4783
+ const onClick = useCallback10(
4775
4784
  (event) => readCaret(event.currentTarget),
4776
4785
  [readCaret]
4777
4786
  );
4778
- const setInput = useCallback9((element) => {
4787
+ const setInput = useCallback10((element) => {
4779
4788
  inputRef.current = element;
4780
4789
  }, []);
4781
- const getInputProps = useCallback9(
4790
+ const getInputProps = useCallback10(
4782
4791
  () => ({
4783
4792
  ref: setInput,
4784
4793
  onChange,
@@ -4805,7 +4814,7 @@ function useComposerAutocomplete(options) {
4805
4814
  optionId
4806
4815
  ]
4807
4816
  );
4808
- const getListboxProps = useCallback9(
4817
+ const getListboxProps = useCallback10(
4809
4818
  () => ({
4810
4819
  id: listboxId,
4811
4820
  role: "listbox",
@@ -4813,7 +4822,7 @@ function useComposerAutocomplete(options) {
4813
4822
  }),
4814
4823
  [listboxId, match]
4815
4824
  );
4816
- const getOptionProps = useCallback9(
4825
+ const getOptionProps = useCallback10(
4817
4826
  (index) => ({
4818
4827
  id: optionId(index),
4819
4828
  role: "option",
@@ -4846,7 +4855,7 @@ function isPromise(value) {
4846
4855
 
4847
4856
  // src/presentation/use-tool-catalog.ts
4848
4857
  import { ALL_AGENTS } from "@dudousxd/nestjs-agent-core";
4849
- import { useCallback as useCallback10, useEffect as useEffect13, useMemo as useMemo10, useState as useState13 } from "react";
4858
+ import { useCallback as useCallback11, useEffect as useEffect13, useMemo as useMemo10, useState as useState13 } from "react";
4850
4859
  var shared2 = /* @__PURE__ */ new WeakMap();
4851
4860
  function load2(client, agent) {
4852
4861
  let byAgent = shared2.get(client);
@@ -4898,7 +4907,7 @@ function useToolCatalog(options = {}) {
4898
4907
  cancelled = true;
4899
4908
  };
4900
4909
  }, [client, agent, enabled, generation]);
4901
- const refresh = useCallback10(() => {
4910
+ const refresh = useCallback11(() => {
4902
4911
  shared2.get(client)?.delete(agent ?? "");
4903
4912
  setGeneration((current) => current + 1);
4904
4913
  }, [client, agent]);
@@ -5065,6 +5074,8 @@ function storedMessageToUiMessage(message) {
5065
5074
  ...message.metadata,
5066
5075
  ...message.feedback !== void 0 ? { feedback: message.feedback } : {},
5067
5076
  ...message.createdAt ? { createdAt: message.createdAt } : {},
5077
+ ...message.agentName !== void 0 ? { agentName: message.agentName } : {},
5078
+ ...message.persona !== void 0 ? { persona: message.persona } : {},
5068
5079
  ...message.usage !== void 0 ? {
5069
5080
  usage: {
5070
5081
  inputTokens: message.usage.inputTokens,
@@ -5115,7 +5126,9 @@ function mergeTurn(rows) {
5115
5126
  ...Object.assign({}, ...rows.map((row) => row.metadata ?? {})),
5116
5127
  ...usage !== void 0 ? { usage } : {},
5117
5128
  ...feedback !== void 0 ? { feedback } : {},
5118
- ...createdAt ? { createdAt } : {}
5129
+ ...createdAt ? { createdAt } : {},
5130
+ ...lastRow.agentName !== void 0 ? { agentName: lastRow.agentName } : {},
5131
+ ...lastRow.persona !== void 0 ? { persona: lastRow.persona } : {}
5119
5132
  };
5120
5133
  return {
5121
5134
  id: lastRow.id,
@@ -5141,7 +5154,7 @@ function sumUsage(rows) {
5141
5154
 
5142
5155
  // src/use-agent-chat.ts
5143
5156
  import { useChat } from "@ai-sdk/react";
5144
- import { useCallback as useCallback11, useEffect as useEffect15, useMemo as useMemo11, useRef as useRef12, useState as useState15 } from "react";
5157
+ import { useCallback as useCallback12, useEffect as useEffect15, useMemo as useMemo11, useRef as useRef12, useState as useState15 } from "react";
5145
5158
  var EMPTY_QUEUE = { items: [], paused: null };
5146
5159
  var localQueueSequence = 0;
5147
5160
  function queuedUserMessage(turn) {
@@ -5222,19 +5235,20 @@ function useAgentChat(options = {}) {
5222
5235
  const [historyError, setHistoryError] = useState15(null);
5223
5236
  const [runError, setRunError] = useState15(null);
5224
5237
  const [threadModel, setThreadModel] = useState15(null);
5238
+ const [threadPersona, setThreadPersona] = useState15(null);
5225
5239
  const [pickedModel, setPickedModel] = useState15(void 0);
5226
5240
  const pickedModelRef = useRef12(pickedModel);
5227
5241
  pickedModelRef.current = pickedModel;
5228
5242
  const lockedRef = useRef12(false);
5229
5243
  const pendingPin = useRef12(void 0);
5230
5244
  const regenerateNext = useRef12(false);
5231
- const currentThreadId = useCallback11(
5245
+ const currentThreadId = useCallback12(
5232
5246
  () => latest.current.threadId ?? createdThreadId.current,
5233
5247
  []
5234
5248
  );
5235
5249
  const [queueState, setQueueState] = useState15(EMPTY_QUEUE);
5236
5250
  const queueStateRef = useRef12(queueState);
5237
- const applyQueue = useCallback11((next) => {
5251
+ const applyQueue = useCallback12((next) => {
5238
5252
  queueStateRef.current = next;
5239
5253
  setQueueState(next);
5240
5254
  }, []);
@@ -5243,8 +5257,9 @@ function useAgentChat(options = {}) {
5243
5257
  const handoff = useRef12(void 0);
5244
5258
  const queuedSend = useRef12(void 0);
5245
5259
  const threadWaiters = useRef12([]);
5246
- const turnBody = useCallback11(() => {
5260
+ const turnBody = useCallback12(() => {
5247
5261
  const current = latest.current;
5262
+ if (current.persona !== void 0) setThreadPersona(current.persona);
5248
5263
  const pageContext = current.getPageContext?.() ?? null;
5249
5264
  const threadId = currentThreadId();
5250
5265
  const model = current.model ?? (lockedRef.current ? void 0 : pickedModelRef.current);
@@ -5252,6 +5267,7 @@ function useAgentChat(options = {}) {
5252
5267
  // Read per send: a host that switches agents before the first message (a picker on a new
5253
5268
  // chat) sends the one picked now, not the one this chat mounted with.
5254
5269
  ...current.agent !== void 0 ? { agent: current.agent } : {},
5270
+ ...current.persona !== void 0 ? { persona: current.persona } : {},
5255
5271
  ...threadId !== void 0 ? { threadId } : {},
5256
5272
  ...model !== void 0 ? { model } : {},
5257
5273
  ...pageContext ? { pageContext } : {}
@@ -5420,6 +5436,7 @@ function useAgentChat(options = {}) {
5420
5436
  setRunId(void 0);
5421
5437
  setActiveRunId(null);
5422
5438
  setThreadModel(null);
5439
+ setThreadPersona(null);
5423
5440
  setPickedModel(void 0);
5424
5441
  setBackgroundRuns([]);
5425
5442
  setHistoryError(null);
@@ -5448,6 +5465,7 @@ function useAgentChat(options = {}) {
5448
5465
  const stored = Array.isArray(thread.messages) ? thread.messages : [];
5449
5466
  setActiveRunId(active);
5450
5467
  setThreadModel(thread.model ?? null);
5468
+ setThreadPersona(thread.persona ?? null);
5451
5469
  setHistoryError(null);
5452
5470
  const queue2 = thread.queue ?? EMPTY_QUEUE;
5453
5471
  applyQueue(queue2);
@@ -5479,7 +5497,7 @@ function useAgentChat(options = {}) {
5479
5497
  }, [client, chatId, options.threadId]);
5480
5498
  const isLoadingHistory = options.threadId !== void 0 && options.threadId !== createdThreadId.current && options.history !== false && options.initialMessages === void 0 && historyFor !== options.threadId;
5481
5499
  const turnInFlight = useRef12(false);
5482
- const isTurnInFlight = useCallback11(
5500
+ const isTurnInFlight = useCallback12(
5483
5501
  () => turnInFlight.current || transport.isAttemptLive,
5484
5502
  [transport]
5485
5503
  );
@@ -5495,13 +5513,13 @@ function useAgentChat(options = {}) {
5495
5513
  whileRunningRef.current = whileRunning;
5496
5514
  const canQueueRef = useRef12(false);
5497
5515
  canQueueRef.current = typeof client.enqueueMessage === "function";
5498
- const threadForQueue = useCallback11(async () => {
5516
+ const threadForQueue = useCallback12(async () => {
5499
5517
  const known = currentThreadId();
5500
5518
  if (known !== void 0) return known;
5501
5519
  if (!isTurnInFlight()) throw new Error("queue: this chat has no thread yet");
5502
5520
  return new Promise((resolve) => threadWaiters.current.push(resolve));
5503
5521
  }, [currentThreadId, isTurnInFlight]);
5504
- const queueCall = useCallback11(async (run) => {
5522
+ const queueCall = useCallback12(async (run) => {
5505
5523
  try {
5506
5524
  const result = await run();
5507
5525
  setQueueError(null);
@@ -5511,7 +5529,7 @@ function useAgentChat(options = {}) {
5511
5529
  throw error;
5512
5530
  }
5513
5531
  }, []);
5514
- const enqueue = useCallback11(
5532
+ const enqueue = useCallback12(
5515
5533
  async (text2, {
5516
5534
  attachments = [],
5517
5535
  mode = "queue"
@@ -5559,7 +5577,7 @@ function useAgentChat(options = {}) {
5559
5577
  },
5560
5578
  [client, queueCall, threadForQueue, turnBody, applyQueue, isTurnInFlight]
5561
5579
  );
5562
- const sendMessage = useCallback11(
5580
+ const sendMessage = useCallback12(
5563
5581
  async (message, options2) => {
5564
5582
  const block = blockedRef.current;
5565
5583
  if (block != null) throw new QuotaBlockedError(block);
@@ -5583,7 +5601,7 @@ function useAgentChat(options = {}) {
5583
5601
  },
5584
5602
  [isTurnInFlight, enqueue]
5585
5603
  );
5586
- const removeQueued = useCallback11(
5604
+ const removeQueued = useCallback12(
5587
5605
  async (id) => {
5588
5606
  const previous = queueStateRef.current;
5589
5607
  applyQueue({ ...previous, items: previous.items.filter((item) => item.id !== id) });
@@ -5596,7 +5614,7 @@ function useAgentChat(options = {}) {
5596
5614
  },
5597
5615
  [client, queueCall, applyQueue]
5598
5616
  );
5599
- const interruptQueued = useCallback11(
5617
+ const interruptQueued = useCallback12(
5600
5618
  async (id) => {
5601
5619
  const previous = queueStateRef.current;
5602
5620
  const moving = previous.items.find((item) => item.id === id);
@@ -5631,7 +5649,7 @@ function useAgentChat(options = {}) {
5631
5649
  },
5632
5650
  [client, queueCall, applyQueue, isTurnInFlight]
5633
5651
  );
5634
- const editQueued = useCallback11(
5652
+ const editQueued = useCallback12(
5635
5653
  async (id, text2) => {
5636
5654
  applyQueue(
5637
5655
  await queueCall(
@@ -5641,7 +5659,7 @@ function useAgentChat(options = {}) {
5641
5659
  },
5642
5660
  [client, queueCall, applyQueue]
5643
5661
  );
5644
- const moveQueued = useCallback11(
5662
+ const moveQueued = useCallback12(
5645
5663
  async (id, index) => {
5646
5664
  const previous = queueStateRef.current;
5647
5665
  const moving = previous.items.find((item) => item.id === id);
@@ -5663,12 +5681,12 @@ function useAgentChat(options = {}) {
5663
5681
  },
5664
5682
  [client, queueCall, applyQueue]
5665
5683
  );
5666
- const clearQueue = useCallback11(async () => {
5684
+ const clearQueue = useCallback12(async () => {
5667
5685
  const threadId = currentThreadId();
5668
5686
  if (threadId === void 0) return;
5669
5687
  applyQueue(await queueCall(() => requireBackendMethod(client, "clearQueue")(threadId)));
5670
5688
  }, [client, queueCall, currentThreadId, applyQueue]);
5671
- const resumeQueue = useCallback11(async () => {
5689
+ const resumeQueue = useCallback12(async () => {
5672
5690
  const threadId = currentThreadId();
5673
5691
  if (threadId === void 0) return;
5674
5692
  const before = queueStateRef.current;
@@ -5716,7 +5734,7 @@ function useAgentChat(options = {}) {
5716
5734
  resume: resumeQueue,
5717
5735
  error: queueError
5718
5736
  };
5719
- const addToolResult = useCallback11(
5737
+ const addToolResult = useCallback12(
5720
5738
  ({ tool, toolCallId, output }) => chatRef.current.addToolResult({
5721
5739
  tool,
5722
5740
  toolCallId,
@@ -5725,7 +5743,7 @@ function useAgentChat(options = {}) {
5725
5743
  []
5726
5744
  );
5727
5745
  const [backgroundRuns, setBackgroundRuns] = useState15([]);
5728
- const refreshBackground = useCallback11(async () => {
5746
+ const refreshBackground = useCallback12(async () => {
5729
5747
  const threadId = currentThreadId();
5730
5748
  if (threadId === void 0) {
5731
5749
  return;
@@ -5759,7 +5777,7 @@ function useAgentChat(options = {}) {
5759
5777
  const timer = setInterval(() => void refreshBackground(), every);
5760
5778
  return () => clearInterval(timer);
5761
5779
  }, [isWorking, refreshBackground]);
5762
- const cancel = useCallback11(async () => {
5780
+ const cancel = useCallback12(async () => {
5763
5781
  chatRef.current.stop();
5764
5782
  const active = runIdRef.current;
5765
5783
  if (active) {
@@ -5776,7 +5794,7 @@ function useAgentChat(options = {}) {
5776
5794
  }
5777
5795
  }
5778
5796
  }, [client, currentThreadId, applyQueue]);
5779
- const approve = useCallback11(
5797
+ const approve = useCallback12(
5780
5798
  async ({ toolCallId, remember, via }) => {
5781
5799
  await requireBackendMethod(
5782
5800
  client,
@@ -5789,7 +5807,7 @@ function useAgentChat(options = {}) {
5789
5807
  },
5790
5808
  [client]
5791
5809
  );
5792
- const reject = useCallback11(
5810
+ const reject = useCallback12(
5793
5811
  async ({ toolCallId, reason, via }) => {
5794
5812
  await requireBackendMethod(
5795
5813
  client,
@@ -5802,7 +5820,7 @@ function useAgentChat(options = {}) {
5802
5820
  },
5803
5821
  [client]
5804
5822
  );
5805
- const answer = useCallback11(
5823
+ const answer = useCallback12(
5806
5824
  async ({ toolCallId, answers, via }) => {
5807
5825
  await requireBackendMethod(
5808
5826
  client,
@@ -5815,7 +5833,7 @@ function useAgentChat(options = {}) {
5815
5833
  },
5816
5834
  [client]
5817
5835
  );
5818
- const skip = useCallback11(
5836
+ const skip = useCallback12(
5819
5837
  async ({ toolCallId, via }) => {
5820
5838
  await requireBackendMethod(
5821
5839
  client,
@@ -5824,7 +5842,7 @@ function useAgentChat(options = {}) {
5824
5842
  },
5825
5843
  [client]
5826
5844
  );
5827
- const regenerate = useCallback11(
5845
+ const regenerate = useCallback12(
5828
5846
  (_input) => {
5829
5847
  const block = blockedRef.current;
5830
5848
  if (block != null) throw new QuotaBlockedError(block);
@@ -5837,7 +5855,7 @@ function useAgentChat(options = {}) {
5837
5855
  },
5838
5856
  [isTurnInFlight]
5839
5857
  );
5840
- const storedIdOf = useCallback11(
5858
+ const storedIdOf = useCallback12(
5841
5859
  async (messageId, threadId) => {
5842
5860
  const message = chatRef.current.messages.find((candidate) => candidate.id === messageId);
5843
5861
  const runOf = message?.metadata?.runId;
@@ -5848,7 +5866,7 @@ function useAgentChat(options = {}) {
5848
5866
  },
5849
5867
  [client]
5850
5868
  );
5851
- const fork = useCallback11(
5869
+ const fork = useCallback12(
5852
5870
  async ({
5853
5871
  messageId,
5854
5872
  threadId
@@ -5863,7 +5881,7 @@ function useAgentChat(options = {}) {
5863
5881
  },
5864
5882
  [client, currentThreadId, storedIdOf]
5865
5883
  );
5866
- const truncateFrom = useCallback11(
5884
+ const truncateFrom = useCallback12(
5867
5885
  async ({ messageId, threadId }) => {
5868
5886
  const target = threadId ?? currentThreadId();
5869
5887
  if (target === void 0) throw new Error("truncateFrom: this chat has no thread yet");
@@ -5872,7 +5890,7 @@ function useAgentChat(options = {}) {
5872
5890
  },
5873
5891
  [client, currentThreadId, storedIdOf]
5874
5892
  );
5875
- const promote = useCallback11(
5893
+ const promote = useCallback12(
5876
5894
  async ({ threadId } = {}) => {
5877
5895
  const target = threadId ?? currentThreadId();
5878
5896
  if (target === void 0) throw new Error("promote: this chat has no thread yet");
@@ -5889,16 +5907,16 @@ function useAgentChat(options = {}) {
5889
5907
  ...options.agent !== void 0 ? { agent: options.agent } : {},
5890
5908
  enabled: modelsWanted && typeof client.listModels === "function"
5891
5909
  });
5892
- const wantModels = useCallback11(() => {
5910
+ const wantModels = useCallback12(() => {
5893
5911
  if (modelsWantedRef.current) return;
5894
5912
  modelsWantedRef.current = true;
5895
5913
  queueMicrotask(() => setModelsWanted(true));
5896
5914
  }, []);
5897
5915
  lockedRef.current = catalog.locked !== null;
5898
- const selectModel = useCallback11((id) => {
5916
+ const selectModel = useCallback12((id) => {
5899
5917
  if (!lockedRef.current) setPickedModel(id);
5900
5918
  }, []);
5901
- const pinToThread = useCallback11(
5919
+ const pinToThread = useCallback12(
5902
5920
  async (model) => {
5903
5921
  const threadId = currentThreadId();
5904
5922
  setThreadModel(model);
@@ -5945,7 +5963,7 @@ function useAgentChat(options = {}) {
5945
5963
  const blockedBy = blocked != null ? "quota" : files.isUploading ? "uploading" : isBusy && whileRunning === "block" ? "busy" : text.trim().length === 0 && files.refs.length === 0 ? "empty" : null;
5946
5964
  const composerRef = useRef12({ text, files, blockedBy });
5947
5965
  composerRef.current = { text, files, blockedBy };
5948
- const submit = useCallback11(
5966
+ const submit = useCallback12(
5949
5967
  async (options2) => {
5950
5968
  const current = composerRef.current;
5951
5969
  const asked = canQueueRef.current ? options2?.mode : void 0;
@@ -6059,6 +6077,11 @@ function useAgentChat(options = {}) {
6059
6077
  queue,
6060
6078
  /** The model picker: `list`, `selected`, `select(id)`, `pinToThread(id)`. */
6061
6079
  models,
6080
+ /**
6081
+ * The persona pinned on this thread (`ThreadSummary.persona`), or `null` when none is — what a
6082
+ * persona picker on a reopened thread starts from (`?? agent.defaultPersona`).
6083
+ */
6084
+ threadPersona,
6062
6085
  /** The caller's budget (`GET <base>/quota`); `quota.blocked` gates sends. */
6063
6086
  quota,
6064
6087
  /** The window blocking sends right now (the `blocked` option, else the quota report's). */