@assistant-ui/react 0.4.4 → 0.4.6

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
@@ -116,6 +116,21 @@ function useAssistantContext(options) {
116
116
  var import_zustand = require("zustand");
117
117
 
118
118
  // src/types/ModelConfigTypes.ts
119
+ var import_zod = require("zod");
120
+ var LanguageModelV1CallSettingsSchema = import_zod.z.object({
121
+ maxTokens: import_zod.z.number().int().positive().optional(),
122
+ temperature: import_zod.z.number().optional(),
123
+ topP: import_zod.z.number().optional(),
124
+ presencePenalty: import_zod.z.number().optional(),
125
+ frequencyPenalty: import_zod.z.number().optional(),
126
+ seed: import_zod.z.number().int().optional(),
127
+ headers: import_zod.z.record(import_zod.z.string().optional()).optional()
128
+ });
129
+ var LanguageModelConfigSchema = import_zod.z.object({
130
+ apiKey: import_zod.z.string().optional(),
131
+ baseUrl: import_zod.z.string().optional(),
132
+ modelName: import_zod.z.string().optional()
133
+ });
119
134
  var mergeModelConfigs = (configSet) => {
120
135
  const configs = Array.from(configSet).map((c) => c.getModelConfig()).sort((a, b) => (b.priority ?? 0) - (a.priority ?? 0));
121
136
  return configs.reduce((acc, config) => {
@@ -1972,7 +1987,7 @@ var ThreadPrimitiveSuggestion = createActionButton(
1972
1987
  );
1973
1988
 
1974
1989
  // src/runtimes/local/useLocalRuntime.tsx
1975
- var import_react53 = require("react");
1990
+ var import_react54 = require("react");
1976
1991
 
1977
1992
  // src/utils/idUtils.tsx
1978
1993
  var import_non_secure = require("nanoid/non-secure");
@@ -2273,163 +2288,8 @@ var TooltipIconButton = (0, import_react52.forwardRef)(({ children, tooltip, sid
2273
2288
  });
2274
2289
  TooltipIconButton.displayName = "TooltipIconButton";
2275
2290
 
2276
- // src/runtimes/local/LocalRuntime.tsx
2277
- var LocalRuntime = class extends BaseAssistantRuntime {
2278
- _proxyConfigProvider;
2279
- constructor(adapter) {
2280
- const proxyConfigProvider = new ProxyConfigProvider();
2281
- super(new LocalThreadRuntime(proxyConfigProvider, adapter));
2282
- this._proxyConfigProvider = proxyConfigProvider;
2283
- }
2284
- set adapter(adapter) {
2285
- this.thread.adapter = adapter;
2286
- }
2287
- registerModelConfigProvider(provider) {
2288
- return this._proxyConfigProvider.registerModelConfigProvider(provider);
2289
- }
2290
- switchToThread(threadId) {
2291
- if (threadId) {
2292
- throw new Error("LocalRuntime does not yet support switching threads");
2293
- }
2294
- return this.thread = new LocalThreadRuntime(
2295
- this._proxyConfigProvider,
2296
- this.thread.adapter
2297
- );
2298
- }
2299
- };
2300
- var CAPABILITIES = Object.freeze({
2301
- edit: true,
2302
- reload: true,
2303
- cancel: true,
2304
- copy: true
2305
- });
2306
- var LocalThreadRuntime = class {
2307
- constructor(configProvider, adapter) {
2308
- this.configProvider = configProvider;
2309
- this.adapter = adapter;
2310
- }
2311
- _subscriptions = /* @__PURE__ */ new Set();
2312
- abortController = null;
2313
- repository = new MessageRepository();
2314
- capabilities = CAPABILITIES;
2315
- get messages() {
2316
- return this.repository.getMessages();
2317
- }
2318
- get isRunning() {
2319
- return this.abortController != null;
2320
- }
2321
- getBranches(messageId) {
2322
- return this.repository.getBranches(messageId);
2323
- }
2324
- switchToBranch(branchId) {
2325
- this.repository.switchToBranch(branchId);
2326
- this.notifySubscribers();
2327
- }
2328
- async append(message) {
2329
- if (message.role !== "user")
2330
- throw new Error(
2331
- "Only appending user messages are supported in LocalRuntime. This is likely an internal bug in assistant-ui."
2332
- );
2333
- const userMessageId = generateId();
2334
- const userMessage = {
2335
- id: userMessageId,
2336
- role: "user",
2337
- content: message.content,
2338
- createdAt: /* @__PURE__ */ new Date()
2339
- };
2340
- this.repository.addOrUpdateMessage(message.parentId, userMessage);
2341
- await this.startRun(userMessageId);
2342
- }
2343
- async startRun(parentId) {
2344
- this.repository.resetHead(parentId);
2345
- const messages = this.repository.getMessages();
2346
- const message = {
2347
- id: generateId(),
2348
- role: "assistant",
2349
- status: { type: "in_progress" },
2350
- content: [{ type: "text", text: "" }],
2351
- createdAt: /* @__PURE__ */ new Date()
2352
- };
2353
- this.repository.addOrUpdateMessage(parentId, { ...message });
2354
- this.abortController?.abort();
2355
- this.abortController = new AbortController();
2356
- this.notifySubscribers();
2357
- try {
2358
- const updateHandler = ({ content }) => {
2359
- message.content = content;
2360
- this.repository.addOrUpdateMessage(parentId, { ...message });
2361
- this.notifySubscribers();
2362
- };
2363
- const result = await this.adapter.run({
2364
- messages,
2365
- abortSignal: this.abortController.signal,
2366
- config: this.configProvider.getModelConfig(),
2367
- onUpdate: updateHandler
2368
- });
2369
- if (result !== void 0) {
2370
- updateHandler(result);
2371
- }
2372
- if (result.status?.type === "in_progress")
2373
- throw new Error(
2374
- "Unexpected in_progress status returned from ChatModelAdapter"
2375
- );
2376
- message.status = result.status ?? { type: "done" };
2377
- this.repository.addOrUpdateMessage(parentId, { ...message });
2378
- } catch (e) {
2379
- message.status = { type: "error", error: e };
2380
- this.repository.addOrUpdateMessage(parentId, { ...message });
2381
- throw e;
2382
- } finally {
2383
- this.abortController = null;
2384
- this.notifySubscribers();
2385
- }
2386
- }
2387
- cancelRun() {
2388
- if (!this.abortController) return;
2389
- this.abortController.abort();
2390
- this.abortController = null;
2391
- }
2392
- notifySubscribers() {
2393
- for (const callback of this._subscriptions) callback();
2394
- }
2395
- subscribe(callback) {
2396
- this._subscriptions.add(callback);
2397
- return () => this._subscriptions.delete(callback);
2398
- }
2399
- addToolResult({ messageId, toolCallId, result }) {
2400
- const { parentId, message } = this.repository.getMessage(messageId);
2401
- if (message.role !== "assistant")
2402
- throw new Error("Tried to add tool result to non-assistant message");
2403
- let found = false;
2404
- const newContent = message.content.map((c) => {
2405
- if (c.type !== "tool-call") return c;
2406
- if (c.toolCallId !== toolCallId) return c;
2407
- found = true;
2408
- return {
2409
- ...c,
2410
- result
2411
- };
2412
- });
2413
- if (!found)
2414
- throw new Error("Tried to add tool result to non-existing tool call");
2415
- this.repository.addOrUpdateMessage(parentId, {
2416
- ...message,
2417
- content: newContent
2418
- });
2419
- }
2420
- };
2421
-
2422
- // src/runtimes/local/useLocalRuntime.tsx
2423
- var useLocalRuntime = (adapter) => {
2424
- const [runtime] = (0, import_react53.useState)(() => new LocalRuntime(adapter));
2425
- (0, import_react53.useInsertionEffect)(() => {
2426
- runtime.adapter = adapter;
2427
- });
2428
- return runtime;
2429
- };
2430
-
2431
2291
  // src/runtimes/edge/useEdgeRuntime.ts
2432
- var import_react54 = require("react");
2292
+ var import_react53 = require("react");
2433
2293
 
2434
2294
  // src/runtimes/edge/converters/toCoreMessages.ts
2435
2295
  var toCoreMessages = (message) => {
@@ -2438,6 +2298,10 @@ var toCoreMessages = (message) => {
2438
2298
  role: message2.role,
2439
2299
  content: message2.content.map((part) => {
2440
2300
  if (part.type === "ui") throw new Error("UI parts are not supported");
2301
+ if (part.type === "tool-call") {
2302
+ const { argsText, ...rest } = part;
2303
+ return rest;
2304
+ }
2441
2305
  return part;
2442
2306
  })
2443
2307
  };
@@ -2445,7 +2309,7 @@ var toCoreMessages = (message) => {
2445
2309
  };
2446
2310
 
2447
2311
  // src/runtimes/edge/converters/toLanguageModelTools.ts
2448
- var import_zod = require("zod");
2312
+ var import_zod2 = require("zod");
2449
2313
  var import_zod_to_json_schema = __toESM(require("zod-to-json-schema"));
2450
2314
  var toLanguageModelTools = (tools) => {
2451
2315
  if (!tools) return [];
@@ -2453,12 +2317,13 @@ var toLanguageModelTools = (tools) => {
2453
2317
  type: "function",
2454
2318
  name,
2455
2319
  ...tool.description ? { description: tool.description } : void 0,
2456
- parameters: tool.parameters instanceof import_zod.z.ZodType ? (0, import_zod_to_json_schema.default)(tool.parameters) : tool.parameters
2320
+ parameters: tool.parameters instanceof import_zod2.z.ZodType ? (0, import_zod_to_json_schema.default)(tool.parameters) : tool.parameters
2457
2321
  }));
2458
2322
  };
2459
2323
 
2460
2324
  // src/runtimes/edge/streams/assistantDecoderStream.ts
2461
2325
  function assistantDecoderStream() {
2326
+ const toolCallNames = /* @__PURE__ */ new Map();
2462
2327
  let currentToolCall;
2463
2328
  return new TransformStream({
2464
2329
  transform(chunk, controller) {
@@ -2483,6 +2348,7 @@ function assistantDecoderStream() {
2483
2348
  }
2484
2349
  case "1" /* ToolCallBegin */: {
2485
2350
  const { id, name } = value;
2351
+ toolCallNames.set(id, name);
2486
2352
  currentToolCall = { id, name, argsText: "" };
2487
2353
  break;
2488
2354
  }
@@ -2498,6 +2364,16 @@ function assistantDecoderStream() {
2498
2364
  });
2499
2365
  break;
2500
2366
  }
2367
+ case "3" /* ToolCallResult */: {
2368
+ controller.enqueue({
2369
+ type: "tool-result",
2370
+ toolCallType: "function",
2371
+ toolCallId: value.id,
2372
+ toolName: toolCallNames.get(value.id),
2373
+ result: value.result
2374
+ });
2375
+ break;
2376
+ }
2501
2377
  case "F" /* Finish */: {
2502
2378
  controller.enqueue({
2503
2379
  type: "finish",
@@ -2884,9 +2760,9 @@ var parsePartialJson = (json) => {
2884
2760
  };
2885
2761
 
2886
2762
  // src/runtimes/edge/streams/runResultStream.ts
2887
- function runResultStream() {
2763
+ function runResultStream(initialContent) {
2888
2764
  let message = {
2889
- content: []
2765
+ content: initialContent
2890
2766
  };
2891
2767
  const currentToolCall = { toolCallId: "", argsText: "" };
2892
2768
  return new TransformStream({
@@ -3018,7 +2894,7 @@ var appendOrUpdateFinish = (message, chunk) => {
3018
2894
  };
3019
2895
 
3020
2896
  // src/runtimes/edge/streams/toolResultStream.ts
3021
- var import_zod2 = require("zod");
2897
+ var import_zod3 = require("zod");
3022
2898
  var import_secure_json_parse2 = __toESM(require("secure-json-parse"));
3023
2899
  function toolResultStream(tools) {
3024
2900
  const toolCallExecutions = /* @__PURE__ */ new Map();
@@ -3032,12 +2908,16 @@ function toolResultStream(tools) {
3032
2908
  const tool = tools?.[toolName];
3033
2909
  if (!tool || !tool.execute) return;
3034
2910
  const args = import_secure_json_parse2.default.parse(argsText);
3035
- if (tool.parameters instanceof import_zod2.z.ZodType) {
2911
+ if (tool.parameters instanceof import_zod3.z.ZodType) {
3036
2912
  const result = tool.parameters.safeParse(args);
3037
2913
  if (!result.success) {
3038
2914
  controller.enqueue({
3039
- type: "error",
3040
- error: new Error("Invalid tool call arguments")
2915
+ type: "tool-result",
2916
+ toolCallType,
2917
+ toolCallId,
2918
+ toolName,
2919
+ result: "Function parameter validation failed. " + JSON.stringify(result.error.issues),
2920
+ isError: true
3041
2921
  });
3042
2922
  return;
3043
2923
  } else {
@@ -3054,9 +2934,14 @@ function toolResultStream(tools) {
3054
2934
  result: result2
3055
2935
  });
3056
2936
  } catch (error) {
2937
+ console.error("Error: ", error);
3057
2938
  controller.enqueue({
3058
- type: "error",
3059
- error
2939
+ type: "tool-result",
2940
+ toolCallType,
2941
+ toolCallId,
2942
+ toolName,
2943
+ result: "Error: " + error,
2944
+ isError: true
3060
2945
  });
3061
2946
  } finally {
3062
2947
  toolCallExecutions.delete(toolCallId);
@@ -3069,6 +2954,7 @@ function toolResultStream(tools) {
3069
2954
  }
3070
2955
  case "text-delta":
3071
2956
  case "tool-call-delta":
2957
+ case "tool-result":
3072
2958
  case "finish":
3073
2959
  case "error":
3074
2960
  break;
@@ -3102,7 +2988,7 @@ var EdgeChatAdapter = class {
3102
2988
  constructor(options) {
3103
2989
  this.options = options;
3104
2990
  }
3105
- async run({ messages, abortSignal, config, onUpdate }) {
2991
+ async roundtrip(initialContent, { messages, abortSignal, config, onUpdate }) {
3106
2992
  const result = await fetch(this.options.api, {
3107
2993
  method: "POST",
3108
2994
  headers: {
@@ -3113,25 +2999,62 @@ var EdgeChatAdapter = class {
3113
2999
  messages: toCoreMessages(messages),
3114
3000
  tools: toLanguageModelTools(
3115
3001
  config.tools
3116
- )
3002
+ ),
3003
+ ...config.callSettings,
3004
+ ...config.config
3117
3005
  }),
3118
3006
  signal: abortSignal
3119
3007
  });
3120
- const stream = result.body.pipeThrough(new TextDecoderStream()).pipeThrough(chunkByLineStream()).pipeThrough(assistantDecoderStream()).pipeThrough(toolResultStream(config.tools)).pipeThrough(runResultStream());
3008
+ const stream = result.body.pipeThrough(new TextDecoderStream()).pipeThrough(chunkByLineStream()).pipeThrough(assistantDecoderStream()).pipeThrough(toolResultStream(config.tools)).pipeThrough(runResultStream(initialContent));
3009
+ let message;
3121
3010
  let update;
3122
3011
  for await (update of asAsyncIterable(stream)) {
3123
- onUpdate(update);
3012
+ message = onUpdate(update);
3124
3013
  }
3125
3014
  if (update === void 0)
3126
3015
  throw new Error("No data received from Edge Runtime");
3127
- return update;
3016
+ return [message, update];
3017
+ }
3018
+ async run({ messages, abortSignal, config, onUpdate }) {
3019
+ let roundtripAllowance = this.options.maxToolRoundtrips ?? 1;
3020
+ let usage = {
3021
+ promptTokens: 0,
3022
+ completionTokens: 0
3023
+ };
3024
+ let result;
3025
+ let assistantMessage;
3026
+ do {
3027
+ [assistantMessage, result] = await this.roundtrip(result?.content ?? [], {
3028
+ messages: assistantMessage ? [...messages, assistantMessage] : messages,
3029
+ abortSignal,
3030
+ config,
3031
+ onUpdate
3032
+ });
3033
+ if (result.status?.type === "done") {
3034
+ usage.promptTokens += result.status.usage?.promptTokens ?? 0;
3035
+ usage.completionTokens += result.status.usage?.completionTokens ?? 0;
3036
+ }
3037
+ } while (result.status?.type === "done" && result.status.finishReason === "tool-calls" && result.content.every((c) => c.type !== "tool-call" || !!c.result) && roundtripAllowance-- > 0);
3038
+ if (result.status?.type === "done" && usage.promptTokens > 0) {
3039
+ result = {
3040
+ ...result,
3041
+ status: {
3042
+ ...result.status,
3043
+ usage
3044
+ }
3045
+ };
3046
+ }
3047
+ return result;
3128
3048
  }
3129
3049
  };
3130
3050
 
3131
3051
  // src/runtimes/edge/useEdgeRuntime.ts
3132
- var useEdgeRuntime = (options) => {
3133
- const [adapter] = (0, import_react54.useState)(() => new EdgeChatAdapter(options));
3134
- return useLocalRuntime(adapter);
3052
+ var useEdgeRuntime = ({
3053
+ initialMessages,
3054
+ ...options
3055
+ }) => {
3056
+ const [adapter] = (0, import_react53.useState)(() => new EdgeChatAdapter(options));
3057
+ return useLocalRuntime(adapter, { initialMessages });
3135
3058
  };
3136
3059
 
3137
3060
  // src/runtimes/edge/converters/toLanguageModelMessages.ts
@@ -3306,7 +3229,7 @@ var fromLanguageModelMessages = (lm, mergeRoundtrips) => {
3306
3229
  toolCallId: part.toolCallId,
3307
3230
  toolName: part.toolName,
3308
3231
  argsText: JSON.stringify(part.args),
3309
- args: typeof part.args === "string" ? part.args : part.args
3232
+ args: part.args
3310
3233
  };
3311
3234
  }
3312
3235
  return part;
@@ -3358,14 +3281,179 @@ var fromLanguageModelMessages = (lm, mergeRoundtrips) => {
3358
3281
  var fromCoreMessages = (message) => {
3359
3282
  return message.map((message2) => {
3360
3283
  return {
3361
- ...message2,
3362
3284
  id: generateId(),
3363
3285
  createdAt: /* @__PURE__ */ new Date(),
3364
3286
  ...message2.role === "assistant" ? {
3365
3287
  status: { type: "done" }
3366
- } : void 0
3288
+ } : void 0,
3289
+ ...message2
3290
+ };
3291
+ });
3292
+ };
3293
+
3294
+ // src/runtimes/local/LocalRuntime.tsx
3295
+ var LocalRuntime = class extends BaseAssistantRuntime {
3296
+ _proxyConfigProvider;
3297
+ constructor(adapter, options) {
3298
+ const proxyConfigProvider = new ProxyConfigProvider();
3299
+ super(new LocalThreadRuntime(proxyConfigProvider, adapter, options));
3300
+ this._proxyConfigProvider = proxyConfigProvider;
3301
+ }
3302
+ set adapter(adapter) {
3303
+ this.thread.adapter = adapter;
3304
+ }
3305
+ registerModelConfigProvider(provider) {
3306
+ return this._proxyConfigProvider.registerModelConfigProvider(provider);
3307
+ }
3308
+ switchToThread(threadId) {
3309
+ if (threadId) {
3310
+ throw new Error("LocalRuntime does not yet support switching threads");
3311
+ }
3312
+ return this.thread = new LocalThreadRuntime(
3313
+ this._proxyConfigProvider,
3314
+ this.thread.adapter
3315
+ );
3316
+ }
3317
+ };
3318
+ var CAPABILITIES = Object.freeze({
3319
+ edit: true,
3320
+ reload: true,
3321
+ cancel: true,
3322
+ copy: true
3323
+ });
3324
+ var LocalThreadRuntime = class {
3325
+ constructor(configProvider, adapter, options) {
3326
+ this.configProvider = configProvider;
3327
+ this.adapter = adapter;
3328
+ if (options?.initialMessages) {
3329
+ let parentId = null;
3330
+ const messages = fromCoreMessages(options.initialMessages);
3331
+ for (const message of messages) {
3332
+ this.repository.addOrUpdateMessage(parentId, message);
3333
+ parentId = message.id;
3334
+ }
3335
+ }
3336
+ }
3337
+ _subscriptions = /* @__PURE__ */ new Set();
3338
+ abortController = null;
3339
+ repository = new MessageRepository();
3340
+ capabilities = CAPABILITIES;
3341
+ get messages() {
3342
+ return this.repository.getMessages();
3343
+ }
3344
+ get isRunning() {
3345
+ return this.abortController != null;
3346
+ }
3347
+ getBranches(messageId) {
3348
+ return this.repository.getBranches(messageId);
3349
+ }
3350
+ switchToBranch(branchId) {
3351
+ this.repository.switchToBranch(branchId);
3352
+ this.notifySubscribers();
3353
+ }
3354
+ async append(message) {
3355
+ if (message.role !== "user")
3356
+ throw new Error(
3357
+ "Only appending user messages are supported in LocalRuntime. This is likely an internal bug in assistant-ui."
3358
+ );
3359
+ const userMessageId = generateId();
3360
+ const userMessage = {
3361
+ id: userMessageId,
3362
+ role: "user",
3363
+ content: message.content,
3364
+ createdAt: /* @__PURE__ */ new Date()
3365
+ };
3366
+ this.repository.addOrUpdateMessage(message.parentId, userMessage);
3367
+ await this.startRun(userMessageId);
3368
+ }
3369
+ async startRun(parentId) {
3370
+ this.repository.resetHead(parentId);
3371
+ const messages = this.repository.getMessages();
3372
+ let message = {
3373
+ id: generateId(),
3374
+ role: "assistant",
3375
+ status: { type: "in_progress" },
3376
+ content: [{ type: "text", text: "" }],
3377
+ createdAt: /* @__PURE__ */ new Date()
3367
3378
  };
3379
+ this.abortController?.abort();
3380
+ this.abortController = new AbortController();
3381
+ this.repository.addOrUpdateMessage(parentId, { ...message });
3382
+ this.notifySubscribers();
3383
+ const updateMessage = (m) => {
3384
+ message = {
3385
+ ...message,
3386
+ ...m
3387
+ };
3388
+ this.repository.addOrUpdateMessage(parentId, message);
3389
+ this.notifySubscribers();
3390
+ return message;
3391
+ };
3392
+ try {
3393
+ const result = await this.adapter.run({
3394
+ messages,
3395
+ abortSignal: this.abortController.signal,
3396
+ config: this.configProvider.getModelConfig(),
3397
+ onUpdate: updateMessage
3398
+ });
3399
+ if (result.status?.type === "in_progress")
3400
+ throw new Error(
3401
+ "Unexpected in_progress status returned from ChatModelAdapter"
3402
+ );
3403
+ this.abortController = null;
3404
+ updateMessage({ status: { type: "done" }, ...result });
3405
+ this.repository.addOrUpdateMessage(parentId, { ...message });
3406
+ } catch (e) {
3407
+ const isAbortError = e instanceof Error && e.name === "AbortError";
3408
+ this.abortController = null;
3409
+ updateMessage({
3410
+ status: isAbortError ? { type: "cancelled" } : { type: "error", error: e }
3411
+ });
3412
+ if (!isAbortError) throw e;
3413
+ }
3414
+ }
3415
+ cancelRun() {
3416
+ if (!this.abortController) return;
3417
+ this.abortController.abort();
3418
+ this.abortController = null;
3419
+ }
3420
+ notifySubscribers() {
3421
+ for (const callback of this._subscriptions) callback();
3422
+ }
3423
+ subscribe(callback) {
3424
+ this._subscriptions.add(callback);
3425
+ return () => this._subscriptions.delete(callback);
3426
+ }
3427
+ addToolResult({ messageId, toolCallId, result }) {
3428
+ const { parentId, message } = this.repository.getMessage(messageId);
3429
+ if (message.role !== "assistant")
3430
+ throw new Error("Tried to add tool result to non-assistant message");
3431
+ let found = false;
3432
+ const newContent = message.content.map((c) => {
3433
+ if (c.type !== "tool-call") return c;
3434
+ if (c.toolCallId !== toolCallId) return c;
3435
+ found = true;
3436
+ return {
3437
+ ...c,
3438
+ result
3439
+ };
3440
+ });
3441
+ if (!found)
3442
+ throw new Error("Tried to add tool result to non-existing tool call");
3443
+ this.repository.addOrUpdateMessage(parentId, {
3444
+ ...message,
3445
+ content: newContent
3446
+ });
3447
+ }
3448
+ };
3449
+
3450
+ // src/runtimes/local/useLocalRuntime.tsx
3451
+ var useLocalRuntime = (adapter, options) => {
3452
+ const [runtime] = (0, import_react54.useState)(() => new LocalRuntime(adapter, options));
3453
+ (0, import_react54.useInsertionEffect)(() => {
3454
+ runtime.adapter = adapter;
3368
3455
  });
3456
+ return runtime;
3369
3457
  };
3370
3458
 
3371
3459
  // src/ui/thread-config.tsx
@@ -3963,10 +4051,7 @@ var ThreadScrollToBottom = (0, import_react64.forwardRef)((props, ref) => {
3963
4051
  thread: { scrollToBottom: { tooltip = "Scroll to bottom" } = {} } = {}
3964
4052
  } = {}
3965
4053
  } = useThreadConfig();
3966
- return /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(thread_exports.ScrollToBottom, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime41.jsxs)(ThreadScrollToBottomIconButton, { tooltip, ...props, ref, children: [
3967
- "|",
3968
- props.children ?? /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(import_lucide_react5.ArrowDownIcon, {})
3969
- ] }) });
4054
+ return /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(thread_exports.ScrollToBottom, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(ThreadScrollToBottomIconButton, { tooltip, ...props, ref, children: props.children ?? /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(import_lucide_react5.ArrowDownIcon, {}) }) });
3970
4055
  });
3971
4056
  ThreadScrollToBottom.displayName = "ThreadScrollToBottom";
3972
4057
  var exports11 = {