@assistant-ui/react 0.5.82 → 0.5.83

Sign up to get free protection for your applications and to get access to all the features.
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,