@assistant-ui/react 0.5.82 → 0.5.83

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.mjs CHANGED
@@ -86,6 +86,10 @@ var { useToolUIs, useToolUIsStore } = createContextStoreHook(
86
86
  useAssistantContext,
87
87
  "useToolUIs"
88
88
  );
89
+ var { useThreadManager } = createContextStoreHook(
90
+ useAssistantContext,
91
+ "useThreadManager"
92
+ );
89
93
 
90
94
  // src/context/stores/AssistantToolUIs.ts
91
95
  import { create } from "zustand";
@@ -260,16 +264,29 @@ var useAssistantRuntimeStore2 = (runtime) => {
260
264
  var useAssistantToolUIsStore = () => {
261
265
  return useMemo2(() => makeAssistantToolUIsStore(), []);
262
266
  };
267
+ var useThreadManagerStore = (runtime) => {
268
+ const [store] = useState3(
269
+ () => create4(() => runtime.threadManager.getState())
270
+ );
271
+ useEffect3(() => {
272
+ const updateState = () => writableStore(store).setState(runtime.threadManager.getState(), true);
273
+ updateState();
274
+ return runtime.threadManager.subscribe(updateState);
275
+ }, [runtime, store]);
276
+ return store;
277
+ };
263
278
  var AssistantRuntimeProviderImpl = ({ children, runtime }) => {
264
279
  const useAssistantRuntime2 = useAssistantRuntimeStore2(runtime);
265
280
  const useToolUIs2 = useAssistantToolUIsStore();
281
+ const useThreadManager2 = useThreadManagerStore(runtime);
266
282
  const context = useMemo2(() => {
267
283
  return {
268
284
  useToolUIs: useToolUIs2,
269
285
  useAssistantRuntime: useAssistantRuntime2,
270
- useAssistantActions: useAssistantRuntime2
286
+ useAssistantActions: useAssistantRuntime2,
287
+ useThreadManager: useThreadManager2
271
288
  };
272
- }, [useAssistantRuntime2, useToolUIs2]);
289
+ }, [useAssistantRuntime2, useToolUIs2, useThreadManager2]);
273
290
  return /* @__PURE__ */ jsx2(AssistantContext.Provider, { value: context, children: /* @__PURE__ */ jsx2(ThreadRuntimeProvider, { runtime: runtime.thread, children }) });
274
291
  };
275
292
  var AssistantRuntimeProvider = memo(AssistantRuntimeProviderImpl);
@@ -3018,13 +3035,13 @@ var subscribeToMainThread = (runtime, callback) => {
3018
3035
  let cleanup;
3019
3036
  const inner = () => {
3020
3037
  cleanup?.();
3021
- cleanup = runtime.thread.subscribe(callback);
3038
+ cleanup = runtime.threadManager.mainThread.subscribe(callback);
3022
3039
  if (!first) {
3023
3040
  callback();
3024
3041
  }
3025
3042
  first = false;
3026
3043
  };
3027
- const unsubscribe = runtime.subscribe(inner);
3044
+ const unsubscribe = runtime.threadManager.mainThread.subscribe(inner);
3028
3045
  inner();
3029
3046
  return () => {
3030
3047
  unsubscribe();
@@ -3033,29 +3050,44 @@ var subscribeToMainThread = (runtime, callback) => {
3033
3050
  };
3034
3051
 
3035
3052
  // src/runtimes/local/useLocalRuntime.tsx
3036
- import { useInsertionEffect, useMemo as useMemo11, useState as useState12 } from "react";
3053
+ import { useEffect as useEffect16, useMemo as useMemo11, useState as useState12 } from "react";
3037
3054
 
3038
- // src/runtimes/core/BaseAssistantRuntimeCore.tsx
3039
- var BaseAssistantRuntimeCore = class {
3040
- constructor(_thread) {
3041
- this._thread = _thread;
3042
- this._thread = _thread;
3055
+ // src/utils/ProxyConfigProvider.ts
3056
+ var ProxyConfigProvider = class {
3057
+ _providers = /* @__PURE__ */ new Set();
3058
+ getModelConfig() {
3059
+ return mergeModelConfigs(this._providers);
3043
3060
  }
3044
- get thread() {
3045
- return this._thread;
3061
+ registerModelConfigProvider(provider) {
3062
+ this._providers.add(provider);
3063
+ const unsubscribe = provider.subscribe?.(() => {
3064
+ this.notifySubscribers();
3065
+ });
3066
+ this.notifySubscribers();
3067
+ return () => {
3068
+ this._providers.delete(provider);
3069
+ unsubscribe?.();
3070
+ this.notifySubscribers();
3071
+ };
3046
3072
  }
3047
- set thread(thread) {
3048
- this._thread = thread;
3049
- this.subscriptionHandler();
3073
+ _subscribers = /* @__PURE__ */ new Set();
3074
+ notifySubscribers() {
3075
+ for (const callback of this._subscribers) callback();
3050
3076
  }
3051
- _subscriptions = /* @__PURE__ */ new Set();
3052
3077
  subscribe(callback) {
3053
- this._subscriptions.add(callback);
3054
- return () => this._subscriptions.delete(callback);
3078
+ this._subscribers.add(callback);
3079
+ return () => this._subscribers.delete(callback);
3080
+ }
3081
+ };
3082
+
3083
+ // src/runtimes/core/BaseAssistantRuntimeCore.tsx
3084
+ var BaseAssistantRuntimeCore = class {
3085
+ _proxyConfigProvider = new ProxyConfigProvider();
3086
+ constructor() {
3087
+ }
3088
+ registerModelConfigProvider(provider) {
3089
+ return this._proxyConfigProvider.registerModelConfigProvider(provider);
3055
3090
  }
3056
- subscriptionHandler = () => {
3057
- for (const callback of this._subscriptions) callback();
3058
- };
3059
3091
  };
3060
3092
 
3061
3093
  // src/internal.ts
@@ -3191,34 +3223,6 @@ var DefaultThreadComposerRuntimeCore = class extends BaseComposerRuntimeCore {
3191
3223
  }
3192
3224
  };
3193
3225
 
3194
- // src/utils/ProxyConfigProvider.ts
3195
- var ProxyConfigProvider = class {
3196
- _providers = /* @__PURE__ */ new Set();
3197
- getModelConfig() {
3198
- return mergeModelConfigs(this._providers);
3199
- }
3200
- registerModelConfigProvider(provider) {
3201
- this._providers.add(provider);
3202
- const unsubscribe = provider.subscribe?.(() => {
3203
- this.notifySubscribers();
3204
- });
3205
- this.notifySubscribers();
3206
- return () => {
3207
- this._providers.delete(provider);
3208
- unsubscribe?.();
3209
- this.notifySubscribers();
3210
- };
3211
- }
3212
- _subscribers = /* @__PURE__ */ new Set();
3213
- notifySubscribers() {
3214
- for (const callback of this._subscribers) callback();
3215
- }
3216
- subscribe(callback) {
3217
- this._subscribers.add(callback);
3218
- return () => this._subscribers.delete(callback);
3219
- }
3220
- };
3221
-
3222
3226
  // src/utils/idUtils.tsx
3223
3227
  import { customAlphabet } from "nanoid/non-secure";
3224
3228
  var generateId = customAlphabet(
@@ -3828,20 +3832,67 @@ var ThreadRuntimeImpl = class {
3828
3832
  }
3829
3833
  };
3830
3834
 
3835
+ // src/api/ThreadManagerRuntime.ts
3836
+ var getThreadManagerState = (threadManager) => {
3837
+ return {
3838
+ threads: threadManager.threads,
3839
+ archivedThreads: threadManager.archivedThreads
3840
+ };
3841
+ };
3842
+ var THREAD_MANAGER_PATH = {
3843
+ ref: "threadManager"
3844
+ };
3845
+ var ThreadManagerRuntimeImpl = class {
3846
+ constructor(_core) {
3847
+ this._core = _core;
3848
+ const stateBinding = new LazyMemoizeSubject({
3849
+ path: THREAD_MANAGER_PATH,
3850
+ getState: () => getThreadManagerState(_core),
3851
+ subscribe: (callback) => _core.subscribe(callback)
3852
+ });
3853
+ this._getState = stateBinding.getState.bind(stateBinding);
3854
+ }
3855
+ get path() {
3856
+ return THREAD_MANAGER_PATH;
3857
+ }
3858
+ _getState;
3859
+ getState() {
3860
+ return this._getState();
3861
+ }
3862
+ rename(threadId, newTitle) {
3863
+ return this._core.rename(threadId, newTitle);
3864
+ }
3865
+ archive(threadId) {
3866
+ return this._core.archive(threadId);
3867
+ }
3868
+ unarchive(threadId) {
3869
+ return this._core.unarchive(threadId);
3870
+ }
3871
+ delete(threadId) {
3872
+ return this._core.delete(threadId);
3873
+ }
3874
+ subscribe(callback) {
3875
+ return this._core.subscribe(callback);
3876
+ }
3877
+ };
3878
+
3831
3879
  // src/api/AssistantRuntime.ts
3832
3880
  var AssistantRuntimeImpl = class _AssistantRuntimeImpl {
3833
3881
  constructor(_core, _thread) {
3834
3882
  this._core = _core;
3835
3883
  this._thread = _thread;
3884
+ this.threadManager = new ThreadManagerRuntimeImpl(_core.threadManager);
3836
3885
  }
3886
+ threadManager;
3837
3887
  get thread() {
3838
3888
  return this._thread;
3839
3889
  }
3840
3890
  switchToNewThread() {
3841
- return this._core.switchToNewThread();
3891
+ return this._core.threadManager.switchToNewThread();
3842
3892
  }
3843
3893
  switchToThread(threadId) {
3844
- return this._core.switchToThread(threadId);
3894
+ if (threadId === null) return this.switchToNewThread();
3895
+ return this._core.threadManager.switchToThread(threadId);
3845
3896
  }
3846
3897
  registerModelConfigProvider(provider) {
3847
3898
  return this._core.registerModelConfigProvider(provider);
@@ -3849,8 +3900,9 @@ var AssistantRuntimeImpl = class _AssistantRuntimeImpl {
3849
3900
  /**
3850
3901
  * @deprecated Thread is now static and never gets updated. This will be removed in 0.6.0.
3851
3902
  */
3852
- subscribe(callback) {
3853
- return this._core.subscribe(callback);
3903
+ subscribe() {
3904
+ return () => {
3905
+ };
3854
3906
  }
3855
3907
  static createMainThreadRuntime(_core, CustomThreadRuntime = ThreadRuntimeImpl) {
3856
3908
  return new CustomThreadRuntime(
@@ -3859,8 +3911,8 @@ var AssistantRuntimeImpl = class _AssistantRuntimeImpl {
3859
3911
  ref: "threads.main",
3860
3912
  threadSelector: { type: "main" }
3861
3913
  },
3862
- getState: () => _core.thread,
3863
- subscribe: (callback) => _core.subscribe(callback)
3914
+ getState: () => _core.threadManager.mainThread,
3915
+ subscribe: (callback) => _core.threadManager.subscribe(callback)
3864
3916
  })
3865
3917
  );
3866
3918
  }
@@ -4272,9 +4324,6 @@ var DefaultEditComposerRuntimeCore = class extends BaseComposerRuntimeCore {
4272
4324
  var BaseThreadRuntimeCore = class {
4273
4325
  constructor(configProvider) {
4274
4326
  this.configProvider = configProvider;
4275
- this.configProvider.subscribe?.(() => {
4276
- this._notifyEventSubscribers("model-config-update");
4277
- });
4278
4327
  }
4279
4328
  _subscriptions = /* @__PURE__ */ new Set();
4280
4329
  repository = new MessageRepository();
@@ -4376,6 +4425,10 @@ var BaseThreadRuntimeCore = class {
4376
4425
  }
4377
4426
  _eventSubscribers = /* @__PURE__ */ new Map();
4378
4427
  unstable_on(event, callback) {
4428
+ if (event === "model-config-update") {
4429
+ return this.configProvider.subscribe?.(callback) ?? (() => {
4430
+ });
4431
+ }
4379
4432
  const subscribers = this._eventSubscribers.get(event);
4380
4433
  if (!subscribers) {
4381
4434
  this._eventSubscribers.set(event, /* @__PURE__ */ new Set([callback]));
@@ -4391,19 +4444,10 @@ var BaseThreadRuntimeCore = class {
4391
4444
 
4392
4445
  // src/runtimes/local/LocalThreadRuntimeCore.tsx
4393
4446
  var LocalThreadRuntimeCore = class extends BaseThreadRuntimeCore {
4394
- constructor(configProvider, adapter, { initialMessages, ...options }) {
4447
+ constructor(configProvider, threadId, options) {
4395
4448
  super(configProvider);
4396
- this.adapter = adapter;
4397
- this.threadId = generateId();
4398
- this.options = options;
4399
- if (initialMessages) {
4400
- let parentId = null;
4401
- const messages2 = fromCoreMessages(initialMessages);
4402
- for (const message of messages2) {
4403
- this.repository.addOrUpdateMessage(parentId, message);
4404
- parentId = message.id;
4405
- }
4406
- }
4449
+ this.threadId = threadId;
4450
+ this._options = options;
4407
4451
  }
4408
4452
  capabilities = {
4409
4453
  switchToBranch: true,
@@ -4416,20 +4460,17 @@ var LocalThreadRuntimeCore = class extends BaseThreadRuntimeCore {
4416
4460
  feedback: false
4417
4461
  };
4418
4462
  abortController = null;
4419
- threadId;
4420
4463
  isDisabled = false;
4421
4464
  suggestions = [];
4422
4465
  get adapters() {
4423
- return this.options.adapters;
4466
+ return this._options.adapters;
4424
4467
  }
4425
4468
  _options;
4426
- get options() {
4427
- return this._options;
4428
- }
4429
4469
  get extras() {
4430
4470
  return void 0;
4431
4471
  }
4432
- set options({ initialMessages, ...options }) {
4472
+ setOptions(options) {
4473
+ if (this._options === options) return;
4433
4474
  this._options = options;
4434
4475
  let hasUpdates = false;
4435
4476
  const canSpeak = options.adapters?.speech !== void 0;
@@ -4505,7 +4546,7 @@ var LocalThreadRuntimeCore = class extends BaseThreadRuntimeCore {
4505
4546
  this.repository.addOrUpdateMessage(parentId, message);
4506
4547
  this._notifySubscribers();
4507
4548
  };
4508
- const maxSteps = this.options.maxSteps ? this.options.maxSteps : (this.options.maxToolRoundtrips ?? 1) + 1;
4549
+ const maxSteps = this._options.maxSteps ? this._options.maxSteps : (this._options.maxToolRoundtrips ?? 1) + 1;
4509
4550
  const steps = message.metadata?.steps?.length ?? 0;
4510
4551
  if (steps >= maxSteps) {
4511
4552
  updateMessage({
@@ -4523,7 +4564,7 @@ var LocalThreadRuntimeCore = class extends BaseThreadRuntimeCore {
4523
4564
  });
4524
4565
  }
4525
4566
  try {
4526
- const promiseOrGenerator = this.adapter.run({
4567
+ const promiseOrGenerator = this.adapters.chatModel.run({
4527
4568
  messages: messages2,
4528
4569
  abortSignal: this.abortController.signal,
4529
4570
  config: this.getModelConfig(),
@@ -4596,44 +4637,154 @@ var LocalThreadRuntimeCore = class extends BaseThreadRuntimeCore {
4596
4637
  }
4597
4638
  };
4598
4639
 
4599
- // src/runtimes/local/LocalRuntimeCore.tsx
4600
- var LocalRuntimeCore = class extends BaseAssistantRuntimeCore {
4601
- _proxyConfigProvider;
4602
- constructor(adapter, options) {
4603
- const proxyConfigProvider = new ProxyConfigProvider();
4604
- super(new LocalThreadRuntimeCore(proxyConfigProvider, adapter, options));
4605
- this._proxyConfigProvider = proxyConfigProvider;
4640
+ // src/runtimes/local/LocalThreadManagerRuntimeCore.tsx
4641
+ var LocalThreadManagerRuntimeCore = class {
4642
+ constructor(_threadFactory) {
4643
+ this._threadFactory = _threadFactory;
4644
+ this._mainThread = this._threadFactory(generateId(), { messages: [] });
4606
4645
  }
4607
- registerModelConfigProvider(provider) {
4608
- return this._proxyConfigProvider.registerModelConfigProvider(provider);
4646
+ _threadData = /* @__PURE__ */ new Map();
4647
+ _threads = [];
4648
+ _archivedThreads = [];
4649
+ get threads() {
4650
+ return this._threads;
4609
4651
  }
4610
- switchToNewThread() {
4611
- const { initialMessages, ...options } = this.thread.options;
4612
- this.thread = new LocalThreadRuntimeCore(
4613
- this._proxyConfigProvider,
4614
- this.thread.adapter,
4615
- options
4616
- );
4617
- this.thread._notifyEventSubscribers("switched-to");
4652
+ get archivedThreads() {
4653
+ return this._archivedThreads;
4654
+ }
4655
+ _mainThread;
4656
+ get mainThread() {
4657
+ return this._mainThread;
4618
4658
  }
4619
4659
  switchToThread(threadId) {
4620
- if (threadId !== null) {
4621
- throw new Error("LocalRuntime does not yet support switching threads");
4660
+ if (this._mainThread.threadId === threadId) return;
4661
+ const data = this._threadData.get(threadId);
4662
+ if (!data) throw new Error("Thread not found");
4663
+ const thread = this._threadFactory(threadId, data.data);
4664
+ this._performThreadSwitch(thread);
4665
+ }
4666
+ switchToNewThread() {
4667
+ if (!this._mainThread) return;
4668
+ const thread = this._threadFactory(generateId(), { messages: [] });
4669
+ this._performThreadSwitch(thread);
4670
+ }
4671
+ _performThreadSwitch(newThreadCore) {
4672
+ if (this._mainThread) {
4673
+ const data = this._threadData.get(this._mainThread.threadId);
4674
+ if (!data) throw new Error("Thread not found");
4675
+ const exprt = this._mainThread.export();
4676
+ data.data = exprt;
4677
+ }
4678
+ this._mainThread._notifyEventSubscribers("switched-away");
4679
+ this._mainThread = newThreadCore;
4680
+ newThreadCore._notifyEventSubscribers("switched-to");
4681
+ this._notifySubscribers();
4682
+ }
4683
+ _performMoveOp(threadId, operation) {
4684
+ const data = this._threadData.get(threadId);
4685
+ if (!data) throw new Error("Thread not found");
4686
+ if (operation === "archive" && data.isArchived) return;
4687
+ if (operation === "unarchive" && !data.isArchived) return;
4688
+ if (operation === "archive") {
4689
+ data.isArchived = true;
4690
+ this._archivedThreads = [...this._archivedThreads, data.metadata];
4691
+ }
4692
+ if (operation === "unarchive") {
4693
+ data.isArchived = false;
4694
+ this._threads = [...this._threads, data.metadata];
4695
+ }
4696
+ if (operation === "delete") {
4697
+ this._threadData.delete(threadId);
4698
+ }
4699
+ if (operation === "archive" || operation === "delete" && data.isArchived) {
4700
+ this._archivedThreads = this._archivedThreads.filter(
4701
+ (t) => t.threadId !== threadId
4702
+ );
4703
+ }
4704
+ if (operation === "unarchive" || operation === "delete" && !data.isArchived) {
4705
+ this._threads = this._threads.filter((t) => t.threadId !== threadId);
4706
+ }
4707
+ this._notifySubscribers();
4708
+ }
4709
+ async rename(threadId, newTitle) {
4710
+ const data = this._threadData.get(threadId);
4711
+ if (!data) throw new Error("Thread not found");
4712
+ data.metadata = {
4713
+ ...data.metadata,
4714
+ title: newTitle
4715
+ };
4716
+ const threadList = data.isArchived ? this.archivedThreads : this.threads;
4717
+ const idx = threadList.findIndex((t) => t.threadId === threadId);
4718
+ const updatedThreadList = threadList.toSpliced(idx, 1, data.metadata);
4719
+ if (data.isArchived) {
4720
+ this._archivedThreads = updatedThreadList;
4721
+ } else {
4722
+ this._threads = updatedThreadList;
4622
4723
  }
4623
- this.switchToNewThread();
4724
+ this._notifySubscribers();
4725
+ }
4726
+ async archive(threadId) {
4727
+ this._performMoveOp(threadId, "archive");
4728
+ }
4729
+ async unarchive(threadId) {
4730
+ this._performMoveOp(threadId, "unarchive");
4731
+ }
4732
+ async delete(threadId) {
4733
+ this._performMoveOp(threadId, "delete");
4734
+ }
4735
+ _subscriptions = /* @__PURE__ */ new Set();
4736
+ subscribe(callback) {
4737
+ this._subscriptions.add(callback);
4738
+ return () => this._subscriptions.delete(callback);
4739
+ }
4740
+ _notifySubscribers() {
4741
+ for (const callback of this._subscriptions) callback();
4742
+ }
4743
+ };
4744
+
4745
+ // src/runtimes/local/LocalRuntimeCore.tsx
4746
+ var getExportFromInitialMessages = (initialMessages) => {
4747
+ const messages2 = fromCoreMessages(initialMessages);
4748
+ return {
4749
+ messages: messages2.map((m, idx) => ({
4750
+ parentId: messages2[idx - 1]?.id ?? null,
4751
+ message: m
4752
+ }))
4753
+ };
4754
+ };
4755
+ var LocalRuntimeCore = class extends BaseAssistantRuntimeCore {
4756
+ threadManager;
4757
+ _options;
4758
+ constructor(options, initialMessages) {
4759
+ super();
4760
+ this._options = options;
4761
+ this.threadManager = new LocalThreadManagerRuntimeCore((threadId, data) => {
4762
+ const thread = new LocalThreadRuntimeCore(
4763
+ this._proxyConfigProvider,
4764
+ threadId,
4765
+ this._options
4766
+ );
4767
+ thread.import(data);
4768
+ return thread;
4769
+ });
4770
+ if (initialMessages) {
4771
+ this.threadManager.mainThread.import(
4772
+ getExportFromInitialMessages(initialMessages)
4773
+ );
4774
+ }
4775
+ }
4776
+ setOptions(options) {
4777
+ this._options = options;
4778
+ this.threadManager.mainThread.setOptions(options);
4624
4779
  }
4625
4780
  reset({
4626
4781
  initialMessages
4627
4782
  } = {}) {
4628
- this.switchToThread(null);
4783
+ this.threadManager.switchToNewThread();
4629
4784
  if (!initialMessages) return;
4630
- const messages2 = fromCoreMessages(initialMessages);
4631
- this.thread.import({
4632
- messages: messages2.map((m, idx) => ({
4633
- parentId: messages2[idx - 1]?.id ?? null,
4634
- message: m
4635
- }))
4636
- });
4785
+ this.threadManager.mainThread.import(
4786
+ getExportFromInitialMessages(initialMessages)
4787
+ );
4637
4788
  }
4638
4789
  };
4639
4790
 
@@ -4654,16 +4805,108 @@ var LocalRuntimeImpl = class _LocalRuntimeImpl extends AssistantRuntimeImpl {
4654
4805
  }
4655
4806
  };
4656
4807
  var useLocalRuntime = (adapter, options = {}) => {
4657
- const [runtime] = useState12(() => new LocalRuntimeCore(adapter, options));
4658
- useInsertionEffect(() => {
4659
- runtime.thread.adapter = adapter;
4660
- runtime.thread.options = options;
4808
+ const opt = {
4809
+ ...options,
4810
+ adapters: {
4811
+ ...options.adapters,
4812
+ chatModel: adapter
4813
+ }
4814
+ };
4815
+ const [runtime] = useState12(() => new LocalRuntimeCore(opt));
4816
+ useEffect16(() => {
4817
+ runtime.setOptions(opt);
4661
4818
  });
4662
4819
  return useMemo11(() => LocalRuntimeImpl.create(runtime), [runtime]);
4663
4820
  };
4664
4821
 
4665
4822
  // src/runtimes/external-store/useExternalStoreRuntime.tsx
4666
- import { useEffect as useEffect16, useMemo as useMemo12, useState as useState13 } from "react";
4823
+ import { useEffect as useEffect17, useMemo as useMemo12, useState as useState13 } from "react";
4824
+
4825
+ // src/runtimes/external-store/ExternalStoreThreadManagementAdapter.tsx
4826
+ var EMPTY_ARRAY2 = Object.freeze([]);
4827
+ var DEFAULT_THREAD_ID = "DEFAULT_THREAD_ID";
4828
+ var ExternalStoreThreadManagerRuntimeCore = class {
4829
+ constructor(adapter = {}, threadFactory) {
4830
+ this.adapter = adapter;
4831
+ this.threadFactory = threadFactory;
4832
+ this._mainThread = this.threadFactory(DEFAULT_THREAD_ID);
4833
+ }
4834
+ get threads() {
4835
+ return this.adapter.threads ?? EMPTY_ARRAY2;
4836
+ }
4837
+ get archivedThreads() {
4838
+ return this.adapter.archivedThreads ?? EMPTY_ARRAY2;
4839
+ }
4840
+ _mainThread;
4841
+ get mainThread() {
4842
+ return this._mainThread;
4843
+ }
4844
+ setAdapter(adapter) {
4845
+ const previousAdapter = this.adapter;
4846
+ this.adapter = adapter;
4847
+ const newThreadId = adapter.threadId ?? DEFAULT_THREAD_ID;
4848
+ const newThreads = adapter.threads ?? EMPTY_ARRAY2;
4849
+ const newArchivedThreads = adapter.archivedThreads ?? EMPTY_ARRAY2;
4850
+ if (previousAdapter.threadId === newThreadId && previousAdapter.threads === newThreads && previousAdapter.archivedThreads === newArchivedThreads) {
4851
+ return;
4852
+ }
4853
+ if (previousAdapter.threadId !== newThreadId) {
4854
+ this._mainThread._notifyEventSubscribers("switched-away");
4855
+ this._mainThread = this.threadFactory(newThreadId);
4856
+ this._mainThread._notifyEventSubscribers("switched-to");
4857
+ }
4858
+ this._notifySubscribers();
4859
+ }
4860
+ switchToThread(threadId) {
4861
+ if (this._mainThread?.threadId === threadId) return;
4862
+ const onSwitchToThread = this.adapter.onSwitchToThread;
4863
+ if (!onSwitchToThread)
4864
+ throw new Error(
4865
+ "External store adapter does not support switching to thread"
4866
+ );
4867
+ onSwitchToThread(threadId);
4868
+ }
4869
+ switchToNewThread() {
4870
+ const onSwitchToNewThread = this.adapter.onSwitchToNewThread;
4871
+ if (!onSwitchToNewThread)
4872
+ throw new Error(
4873
+ "External store adapter does not support switching to new thread"
4874
+ );
4875
+ onSwitchToNewThread();
4876
+ }
4877
+ async rename(threadId, newTitle) {
4878
+ const onRename = this.adapter.onRename;
4879
+ if (!onRename)
4880
+ throw new Error("External store adapter does not support renaming");
4881
+ onRename(threadId, newTitle);
4882
+ }
4883
+ async archive(threadId) {
4884
+ const onArchive = this.adapter.onArchive;
4885
+ if (!onArchive)
4886
+ throw new Error("External store adapter does not support archiving");
4887
+ onArchive(threadId);
4888
+ }
4889
+ async unarchive(threadId) {
4890
+ const onUnarchive = this.adapter.onUnarchive;
4891
+ if (!onUnarchive)
4892
+ throw new Error("External store adapter does not support unarchiving");
4893
+ onUnarchive(threadId);
4894
+ }
4895
+ async delete(threadId) {
4896
+ const onDelete = this.adapter.onDelete;
4897
+ if (!onDelete)
4898
+ throw new Error("External store adapter does not support deleting");
4899
+ onDelete(threadId);
4900
+ }
4901
+ _subscriptions = /* @__PURE__ */ new Set();
4902
+ subscribe(callback) {
4903
+ this._subscriptions.add(callback);
4904
+ return () => this._subscriptions.delete(callback);
4905
+ }
4906
+ _notifySubscribers() {
4907
+ for (const callback of this._subscriptions) callback();
4908
+ }
4909
+ };
4667
4910
 
4668
4911
  // src/runtimes/external-store/getExternalStoreMessage.tsx
4669
4912
  var symbolInnerMessage = Symbol("innerMessage");
@@ -4768,7 +5011,7 @@ var fromThreadMessageLike = (like, fallbackId, fallbackStatus) => {
4768
5011
  };
4769
5012
 
4770
5013
  // src/runtimes/external-store/ExternalStoreThreadRuntimeCore.tsx
4771
- var EMPTY_ARRAY2 = Object.freeze([]);
5014
+ var EMPTY_ARRAY3 = Object.freeze([]);
4772
5015
  var hasUpcomingMessage = (isRunning, messages2) => {
4773
5016
  return isRunning && messages2[messages2.length - 1]?.role !== "assistant";
4774
5017
  };
@@ -4801,26 +5044,23 @@ var ExternalStoreThreadRuntimeCore = class extends BaseThreadRuntimeCore {
4801
5044
  _converter = new ThreadMessageConverter();
4802
5045
  _store;
4803
5046
  beginEdit(messageId) {
4804
- if (!this.store.onEdit)
5047
+ if (!this._store.onEdit)
4805
5048
  throw new Error("Runtime does not support editing.");
4806
5049
  super.beginEdit(messageId);
4807
5050
  }
4808
- constructor(configProvider, store) {
5051
+ constructor(configProvider, threadId, store) {
4809
5052
  super(configProvider);
4810
- this.store = store;
5053
+ this.threadId = threadId;
5054
+ this.setStore(store);
4811
5055
  }
4812
- get store() {
4813
- return this._store;
4814
- }
4815
- set store(store) {
5056
+ setStore(store) {
4816
5057
  if (this._store === store) return;
4817
- this.threadId = store.threadId ?? this.threadId ?? generateId();
4818
5058
  const isRunning = store.isRunning ?? false;
4819
5059
  this.isDisabled = store.isDisabled ?? false;
4820
5060
  const oldStore = this._store;
4821
5061
  this._store = store;
4822
5062
  this.extras = store.extras;
4823
- this.suggestions = store.suggestions ?? EMPTY_ARRAY2;
5063
+ this.suggestions = store.suggestions ?? EMPTY_ARRAY3;
4824
5064
  this._capabilities = {
4825
5065
  switchToBranch: this._store.setMessages !== void 0,
4826
5066
  edit: this._store.onEdit !== void 0,
@@ -4829,8 +5069,8 @@ var ExternalStoreThreadRuntimeCore = class extends BaseThreadRuntimeCore {
4829
5069
  speech: this._store.adapters?.speech !== void 0,
4830
5070
  unstable_copy: this._store.unstable_capabilities?.copy !== false,
4831
5071
  // default true
4832
- attachments: !!this.store.adapters?.attachments,
4833
- feedback: !!this.store.adapters?.feedback
5072
+ attachments: !!this._store.adapters?.attachments,
5073
+ feedback: !!this._store.adapters?.feedback
4834
5074
  };
4835
5075
  if (oldStore) {
4836
5076
  if (oldStore.convertMessage !== store.convertMessage) {
@@ -4934,57 +5174,41 @@ var ExternalStoreThreadRuntimeCore = class extends BaseThreadRuntimeCore {
4934
5174
  };
4935
5175
 
4936
5176
  // src/runtimes/external-store/ExternalStoreRuntimeCore.tsx
5177
+ var getThreadManagerAdapter = (store) => {
5178
+ return {
5179
+ threadId: store.threadId,
5180
+ onSwitchToNewThread: store.onSwitchToNewThread,
5181
+ onSwitchToThread: store.onSwitchToThread,
5182
+ ...store.adapters?.threadManager
5183
+ };
5184
+ };
4937
5185
  var ExternalStoreRuntimeCore = class extends BaseAssistantRuntimeCore {
4938
- _proxyConfigProvider;
5186
+ threadManager;
5187
+ _store;
4939
5188
  constructor(store) {
4940
- const provider = new ProxyConfigProvider();
4941
- super(new ExternalStoreThreadRuntimeCore(provider, store));
4942
- this._proxyConfigProvider = provider;
4943
- }
4944
- getModelConfig() {
4945
- return this._proxyConfigProvider.getModelConfig();
4946
- }
4947
- registerModelConfigProvider(provider) {
4948
- return this._proxyConfigProvider.registerModelConfigProvider(provider);
4949
- }
4950
- async switchToNewThread() {
4951
- if (!this.thread.store.onSwitchToNewThread)
4952
- throw new Error("Runtime does not support switching to new threads.");
4953
- this.thread = new ExternalStoreThreadRuntimeCore(
4954
- this._proxyConfigProvider,
4955
- {
4956
- ...this.thread.store,
4957
- messages: []
4958
- }
4959
- );
4960
- await this.thread.store.onSwitchToNewThread();
4961
- this.thread._notifyEventSubscribers("switched-to");
4962
- }
4963
- async switchToThread(threadId) {
4964
- if (threadId !== null) {
4965
- if (!this.thread.store.onSwitchToThread)
4966
- throw new Error("Runtime does not support switching threads.");
4967
- this.thread = new ExternalStoreThreadRuntimeCore(
5189
+ super();
5190
+ this._store = store;
5191
+ this.threadManager = new ExternalStoreThreadManagerRuntimeCore(
5192
+ getThreadManagerAdapter(store),
5193
+ (threadId) => new ExternalStoreThreadRuntimeCore(
4968
5194
  this._proxyConfigProvider,
4969
- {
4970
- ...this.thread.store,
4971
- messages: []
4972
- // ignore messages until rerender
4973
- }
4974
- );
4975
- await this.thread.store.onSwitchToThread(threadId);
4976
- this.thread._notifyEventSubscribers("switched-to");
4977
- } else {
4978
- this.switchToNewThread();
4979
- }
5195
+ threadId,
5196
+ this._store
5197
+ )
5198
+ );
5199
+ }
5200
+ setStore(store) {
5201
+ this._store = store;
5202
+ this.threadManager.setAdapter(getThreadManagerAdapter(store));
5203
+ this.threadManager.mainThread.setStore(store);
4980
5204
  }
4981
5205
  };
4982
5206
 
4983
5207
  // src/runtimes/external-store/useExternalStoreRuntime.tsx
4984
5208
  var useExternalStoreRuntime = (store) => {
4985
5209
  const [runtime] = useState13(() => new ExternalStoreRuntimeCore(store));
4986
- useEffect16(() => {
4987
- runtime.thread.store = store;
5210
+ useEffect17(() => {
5211
+ runtime.setStore(store);
4988
5212
  });
4989
5213
  return useMemo12(
4990
5214
  () => AssistantRuntimeImpl.create(runtime, ThreadRuntimeImpl),
@@ -5754,7 +5978,7 @@ CircleStopIcon.displayName = "CircleStopIcon";
5754
5978
  // src/ui/attachment.tsx
5755
5979
  import {
5756
5980
  forwardRef as forwardRef28,
5757
- useEffect as useEffect17,
5981
+ useEffect as useEffect18,
5758
5982
  useState as useState15
5759
5983
  } from "react";
5760
5984
  import { CircleXIcon, FileIcon } from "lucide-react";
@@ -5799,7 +6023,7 @@ var AttachmentRoot = withDefaults(attachment_exports.Root, {
5799
6023
  AttachmentRoot.displayName = "AttachmentRoot";
5800
6024
  var useFileSrc = (file) => {
5801
6025
  const [src, setSrc] = useState15(void 0);
5802
- useEffect17(() => {
6026
+ useEffect18(() => {
5803
6027
  if (!file) {
5804
6028
  setSrc(void 0);
5805
6029
  return;
@@ -6069,8 +6293,13 @@ var ThreadWelcomeMessageStyled = withDefaults("p", {
6069
6293
  className: "aui-thread-welcome-message"
6070
6294
  });
6071
6295
  var ThreadWelcomeMessage = forwardRef30(({ message: messageProp, ...rest }, ref) => {
6072
- const { welcome: { message = "How can I help you today?" } = {} } = useThreadConfig();
6073
- return /* @__PURE__ */ jsx48(ThreadWelcomeMessageStyled, { ...rest, ref, children: messageProp ?? message });
6296
+ const {
6297
+ welcome: { message } = {},
6298
+ strings: {
6299
+ welcome: { message: defaultMessage = "How can I help you today?" } = {}
6300
+ } = {}
6301
+ } = useThreadConfig();
6302
+ return /* @__PURE__ */ jsx48(ThreadWelcomeMessageStyled, { ...rest, ref, children: messageProp ?? message ?? defaultMessage });
6074
6303
  });
6075
6304
  ThreadWelcomeMessage.displayName = "ThreadWelcomeMessage";
6076
6305
  var ThreadWelcomeSuggestionContainer = withDefaults("div", {
@@ -6522,6 +6751,7 @@ export {
6522
6751
  useThreadContext,
6523
6752
  useThreadEmpty,
6524
6753
  useThreadIf,
6754
+ useThreadManager,
6525
6755
  useThreadMessages,
6526
6756
  useThreadMessagesStore,
6527
6757
  useThreadModelConfig,