@assistant-ui/react 0.7.65 → 0.7.66

Sign up to get free protection for your applications and to get access to all the features.
Files changed (117) hide show
  1. package/dist/api/ThreadListItemRuntime.d.ts +2 -0
  2. package/dist/api/ThreadListItemRuntime.d.ts.map +1 -1
  3. package/dist/api/ThreadListItemRuntime.js +5 -0
  4. package/dist/api/ThreadListItemRuntime.js.map +1 -1
  5. package/dist/api/ThreadListItemRuntime.mjs +5 -0
  6. package/dist/api/ThreadListItemRuntime.mjs.map +1 -1
  7. package/dist/cloud/AssistantCloudThreads.d.ts +1 -1
  8. package/dist/cloud/AssistantCloudThreads.d.ts.map +1 -1
  9. package/dist/cloud/AssistantCloudThreads.js.map +1 -1
  10. package/dist/cloud/AssistantCloudThreads.mjs.map +1 -1
  11. package/dist/cloud/useCloudThreadListRuntime.d.ts +1 -1
  12. package/dist/cloud/useCloudThreadListRuntime.d.ts.map +1 -1
  13. package/dist/cloud/useCloudThreadListRuntime.js +8 -83
  14. package/dist/cloud/useCloudThreadListRuntime.js.map +1 -1
  15. package/dist/cloud/useCloudThreadListRuntime.mjs +8 -89
  16. package/dist/cloud/useCloudThreadListRuntime.mjs.map +1 -1
  17. package/dist/runtimes/core/ThreadListRuntimeCore.d.ts +1 -0
  18. package/dist/runtimes/core/ThreadListRuntimeCore.d.ts.map +1 -1
  19. package/dist/runtimes/core/ThreadListRuntimeCore.js.map +1 -1
  20. package/dist/runtimes/dangerous-in-browser/useDangerousInBrowserRuntime.d.ts +1 -1
  21. package/dist/runtimes/dangerous-in-browser/useDangerousInBrowserRuntime.d.ts.map +1 -1
  22. package/dist/runtimes/edge/EdgeChatAdapter.d.ts +22 -3
  23. package/dist/runtimes/edge/EdgeChatAdapter.d.ts.map +1 -1
  24. package/dist/runtimes/edge/EdgeChatAdapter.js +44 -13
  25. package/dist/runtimes/edge/EdgeChatAdapter.js.map +1 -1
  26. package/dist/runtimes/edge/EdgeChatAdapter.mjs +34 -13
  27. package/dist/runtimes/edge/EdgeChatAdapter.mjs.map +1 -1
  28. package/dist/runtimes/edge/useEdgeRuntime.d.ts +1 -1
  29. package/dist/runtimes/edge/useEdgeRuntime.d.ts.map +1 -1
  30. package/dist/runtimes/external-store/ExternalStoreThreadListRuntimeCore.d.ts +1 -0
  31. package/dist/runtimes/external-store/ExternalStoreThreadListRuntimeCore.d.ts.map +1 -1
  32. package/dist/runtimes/external-store/ExternalStoreThreadListRuntimeCore.js +3 -0
  33. package/dist/runtimes/external-store/ExternalStoreThreadListRuntimeCore.js.map +1 -1
  34. package/dist/runtimes/external-store/ExternalStoreThreadListRuntimeCore.mjs +3 -0
  35. package/dist/runtimes/external-store/ExternalStoreThreadListRuntimeCore.mjs.map +1 -1
  36. package/dist/runtimes/local/ChatModelAdapter.d.ts +1 -0
  37. package/dist/runtimes/local/ChatModelAdapter.d.ts.map +1 -1
  38. package/dist/runtimes/local/ChatModelAdapter.js.map +1 -1
  39. package/dist/runtimes/local/LocalRuntimeOptions.d.ts +4 -1
  40. package/dist/runtimes/local/LocalRuntimeOptions.d.ts.map +1 -1
  41. package/dist/runtimes/local/LocalRuntimeOptions.js +2 -0
  42. package/dist/runtimes/local/LocalRuntimeOptions.js.map +1 -1
  43. package/dist/runtimes/local/LocalRuntimeOptions.mjs +2 -0
  44. package/dist/runtimes/local/LocalRuntimeOptions.mjs.map +1 -1
  45. package/dist/runtimes/local/LocalThreadListRuntimeCore.d.ts +21 -31
  46. package/dist/runtimes/local/LocalThreadListRuntimeCore.d.ts.map +1 -1
  47. package/dist/runtimes/local/LocalThreadListRuntimeCore.js +43 -147
  48. package/dist/runtimes/local/LocalThreadListRuntimeCore.js.map +1 -1
  49. package/dist/runtimes/local/LocalThreadListRuntimeCore.mjs +43 -147
  50. package/dist/runtimes/local/LocalThreadListRuntimeCore.mjs.map +1 -1
  51. package/dist/runtimes/local/LocalThreadRuntimeCore.d.ts.map +1 -1
  52. package/dist/runtimes/local/LocalThreadRuntimeCore.js +4 -1
  53. package/dist/runtimes/local/LocalThreadRuntimeCore.js.map +1 -1
  54. package/dist/runtimes/local/LocalThreadRuntimeCore.mjs +4 -1
  55. package/dist/runtimes/local/LocalThreadRuntimeCore.mjs.map +1 -1
  56. package/dist/runtimes/local/useLocalRuntime.d.ts +1 -1
  57. package/dist/runtimes/local/useLocalRuntime.d.ts.map +1 -1
  58. package/dist/runtimes/local/useLocalRuntime.js +10 -1
  59. package/dist/runtimes/local/useLocalRuntime.js.map +1 -1
  60. package/dist/runtimes/local/useLocalRuntime.mjs +10 -1
  61. package/dist/runtimes/local/useLocalRuntime.mjs.map +1 -1
  62. package/dist/runtimes/remote-thread-list/RemoteThreadListHookInstanceManager.d.ts.map +1 -1
  63. package/dist/runtimes/remote-thread-list/RemoteThreadListHookInstanceManager.js +4 -0
  64. package/dist/runtimes/remote-thread-list/RemoteThreadListHookInstanceManager.js.map +1 -1
  65. package/dist/runtimes/remote-thread-list/RemoteThreadListHookInstanceManager.mjs +4 -0
  66. package/dist/runtimes/remote-thread-list/RemoteThreadListHookInstanceManager.mjs.map +1 -1
  67. package/dist/runtimes/remote-thread-list/RemoteThreadListThreadListRuntimeCore.d.ts +6 -6
  68. package/dist/runtimes/remote-thread-list/RemoteThreadListThreadListRuntimeCore.d.ts.map +1 -1
  69. package/dist/runtimes/remote-thread-list/RemoteThreadListThreadListRuntimeCore.js +25 -23
  70. package/dist/runtimes/remote-thread-list/RemoteThreadListThreadListRuntimeCore.js.map +1 -1
  71. package/dist/runtimes/remote-thread-list/RemoteThreadListThreadListRuntimeCore.mjs +25 -23
  72. package/dist/runtimes/remote-thread-list/RemoteThreadListThreadListRuntimeCore.mjs.map +1 -1
  73. package/dist/runtimes/remote-thread-list/adapter/cloud.d.ts +13 -0
  74. package/dist/runtimes/remote-thread-list/adapter/cloud.d.ts.map +1 -0
  75. package/dist/runtimes/remote-thread-list/adapter/cloud.js +96 -0
  76. package/dist/runtimes/remote-thread-list/adapter/cloud.js.map +1 -0
  77. package/dist/runtimes/remote-thread-list/adapter/cloud.mjs +76 -0
  78. package/dist/runtimes/remote-thread-list/adapter/cloud.mjs.map +1 -0
  79. package/dist/runtimes/remote-thread-list/adapter/in-memory.d.ts +12 -0
  80. package/dist/runtimes/remote-thread-list/adapter/in-memory.d.ts.map +1 -0
  81. package/dist/runtimes/remote-thread-list/adapter/in-memory.js +58 -0
  82. package/dist/runtimes/remote-thread-list/adapter/in-memory.js.map +1 -0
  83. package/dist/runtimes/remote-thread-list/adapter/in-memory.mjs +35 -0
  84. package/dist/runtimes/remote-thread-list/adapter/in-memory.mjs.map +1 -0
  85. package/dist/runtimes/remote-thread-list/index.d.ts +2 -1
  86. package/dist/runtimes/remote-thread-list/index.d.ts.map +1 -1
  87. package/dist/runtimes/remote-thread-list/index.js +3 -0
  88. package/dist/runtimes/remote-thread-list/index.js.map +1 -1
  89. package/dist/runtimes/remote-thread-list/index.mjs +2 -0
  90. package/dist/runtimes/remote-thread-list/index.mjs.map +1 -1
  91. package/dist/runtimes/remote-thread-list/types.d.ts +6 -6
  92. package/dist/runtimes/remote-thread-list/types.d.ts.map +1 -1
  93. package/dist/runtimes/remote-thread-list/types.js.map +1 -1
  94. package/dist/runtimes/remote-thread-list/useRemoteThreadListRuntime.d.ts +2 -2
  95. package/dist/runtimes/remote-thread-list/useRemoteThreadListRuntime.js +7 -7
  96. package/dist/runtimes/remote-thread-list/useRemoteThreadListRuntime.js.map +1 -1
  97. package/dist/runtimes/remote-thread-list/useRemoteThreadListRuntime.mjs +7 -7
  98. package/dist/runtimes/remote-thread-list/useRemoteThreadListRuntime.mjs.map +1 -1
  99. package/package.json +1 -1
  100. package/src/api/ThreadListItemRuntime.ts +8 -0
  101. package/src/cloud/AssistantCloudThreads.tsx +1 -1
  102. package/src/cloud/useCloudThreadListRuntime.tsx +8 -110
  103. package/src/runtimes/core/ThreadListRuntimeCore.tsx +1 -0
  104. package/src/runtimes/edge/EdgeChatAdapter.ts +90 -19
  105. package/src/runtimes/external-store/ExternalStoreThreadListRuntimeCore.tsx +4 -0
  106. package/src/runtimes/local/ChatModelAdapter.tsx +1 -0
  107. package/src/runtimes/local/LocalRuntimeOptions.tsx +4 -0
  108. package/src/runtimes/local/LocalThreadListRuntimeCore.tsx +47 -190
  109. package/src/runtimes/local/LocalThreadRuntimeCore.tsx +3 -0
  110. package/src/runtimes/local/useLocalRuntime.tsx +15 -2
  111. package/src/runtimes/remote-thread-list/RemoteThreadListHookInstanceManager.tsx +7 -0
  112. package/src/runtimes/remote-thread-list/RemoteThreadListThreadListRuntimeCore.tsx +27 -28
  113. package/src/runtimes/remote-thread-list/adapter/cloud.tsx +99 -0
  114. package/src/runtimes/remote-thread-list/adapter/in-memory.tsx +43 -0
  115. package/src/runtimes/remote-thread-list/index.ts +3 -4
  116. package/src/runtimes/remote-thread-list/types.tsx +10 -12
  117. package/src/runtimes/remote-thread-list/useRemoteThreadListRuntime.tsx +8 -8
@@ -11,6 +11,11 @@ import { streamPartDecoderStream } from "./streams/utils/streamPartDecoderStream
11
11
  import { runResultStream } from "./streams/runResultStream";
12
12
  import { toolResultStream } from "./streams/toolResultStream";
13
13
  import { toLanguageModelMessages } from "./converters";
14
+ import { ThreadMessage } from "../../types";
15
+ import { Tool } from "../../model-context";
16
+ import { z } from "zod";
17
+ import zodToJsonSchema from "zod-to-json-schema";
18
+ import { JSONSchema7 } from "json-schema";
14
19
 
15
20
  export function asAsyncIterable<T>(
16
21
  source: ReadableStream<T>,
@@ -29,23 +34,71 @@ export function asAsyncIterable<T>(
29
34
  },
30
35
  };
31
36
  }
37
+
32
38
  export type EdgeChatAdapterOptions = {
33
39
  api: string;
34
40
 
41
+ // experimental_prepareRequestBody?: (options: {
42
+ // id: string;
43
+ // messages: UIMessage[];
44
+ // requestData?: JSONValue;
45
+ // requestBody?: object;
46
+ // }) => unknown;
47
+
48
+ // onToolCall?: ({
49
+ // toolCall,
50
+ // }: {
51
+ // toolCall: UIMessageToolInvocation;
52
+ // }) => void | Promise<unknown> | unknown;
53
+
54
+ /**
55
+ * Callback function to be called when the API response is received.
56
+ */
57
+ onResponse?: (response: Response) => void | Promise<void>;
58
+ /**
59
+ * Optional callback function that is called when the assistant message is finished streaming.
60
+ */
61
+ onFinish?: (message: ThreadMessage) => void;
62
+ /**
63
+ * Callback function to be called when an error is encountered.
64
+ */
65
+ onError?: (error: Error) => void;
66
+
35
67
  credentials?: RequestCredentials;
36
68
  headers?: Record<string, string> | Headers;
37
69
  body?: object;
38
70
 
39
71
  /**
40
- * When enabled, the adapter will not strip `id` from messages in the messages array.
72
+ * @deprecated Renamed to `sendExtraMessageFields`.
41
73
  */
42
74
  unstable_sendMessageIds?: boolean;
43
75
 
76
+ /**
77
+ * When enabled, the adapter will not strip `id` from messages in the messages array.
78
+ */
79
+ sendExtraMessageFields?: boolean;
80
+
44
81
  /**
45
82
  * When enabled, the adapter will send messages in the format expected by the Vercel AI SDK Core.
46
83
  * This feature will be removed in the future in favor of a better solution.
84
+ *
85
+ * `v2` sends frontend tools in a format that can be directly passed to `stremaText`
47
86
  */
48
- unstable_AISDKInterop?: boolean | undefined;
87
+ unstable_AISDKInterop?: boolean | "v2" | undefined;
88
+ };
89
+
90
+ const toAISDKTools = (tools: Record<string, Tool<any, any>>) => {
91
+ return Object.fromEntries(
92
+ Object.entries(tools).map(([name, tool]) => [
93
+ name,
94
+ {
95
+ ...(tool.description ? { description: tool.description } : undefined),
96
+ parameters: (tool.parameters instanceof z.ZodType
97
+ ? zodToJsonSchema(tool.parameters)
98
+ : tool.parameters) as JSONSchema7,
99
+ },
100
+ ]),
101
+ );
49
102
  };
50
103
 
51
104
  export class EdgeChatAdapter implements ChatModelAdapter {
@@ -57,6 +110,7 @@ export class EdgeChatAdapter implements ChatModelAdapter {
57
110
  abortSignal,
58
111
  context,
59
112
  unstable_assistantMessageId,
113
+ unstable_getMessage,
60
114
  }: ChatModelRunOptions) {
61
115
  const headers = new Headers(this.options.headers);
62
116
  headers.set("Content-Type", "application/json");
@@ -69,12 +123,20 @@ export class EdgeChatAdapter implements ChatModelAdapter {
69
123
  system: context.system,
70
124
  messages: this.options.unstable_AISDKInterop
71
125
  ? (toLanguageModelMessages(messages, {
72
- unstable_includeId: this.options.unstable_sendMessageIds,
126
+ unstable_includeId:
127
+ this.options.unstable_sendMessageIds ||
128
+ this.options.sendExtraMessageFields,
73
129
  }) as EdgeRuntimeRequestOptions["messages"]) // TODO figure out a better way to do this
74
130
  : toCoreMessages(messages, {
75
- unstable_includeId: this.options.unstable_sendMessageIds,
131
+ unstable_includeId:
132
+ this.options.unstable_sendMessageIds ||
133
+ this.options.sendExtraMessageFields,
76
134
  }),
77
- tools: context.tools ? toLanguageModelTools(context.tools) : [],
135
+ tools: context.tools
136
+ ? this.options.unstable_AISDKInterop === "v2"
137
+ ? (toAISDKTools(context.tools) as any)
138
+ : toLanguageModelTools(context.tools)
139
+ : [],
78
140
  unstable_assistantMessageId,
79
141
  runConfig,
80
142
  ...context.callSettings,
@@ -85,22 +147,31 @@ export class EdgeChatAdapter implements ChatModelAdapter {
85
147
  signal: abortSignal,
86
148
  });
87
149
 
88
- if (!result.ok) {
89
- throw new Error(`Status ${result.status}: ${await result.text()}`);
90
- }
150
+ await this.options.onResponse?.(result);
91
151
 
92
- const stream = result
93
- .body!.pipeThrough(streamPartDecoderStream())
94
- .pipeThrough(assistantDecoderStream())
95
- .pipeThrough(toolResultStream(context.tools, abortSignal))
96
- .pipeThrough(runResultStream());
152
+ try {
153
+ if (!result.ok) {
154
+ throw new Error(`Status ${result.status}: ${await result.text()}`);
155
+ }
97
156
 
98
- let update: ChatModelRunResult | undefined;
99
- for await (update of asAsyncIterable(stream)) {
100
- yield update;
101
- }
157
+ const stream = result
158
+ .body!.pipeThrough(streamPartDecoderStream())
159
+ .pipeThrough(assistantDecoderStream())
160
+ .pipeThrough(toolResultStream(context.tools, abortSignal))
161
+ .pipeThrough(runResultStream());
162
+
163
+ let update: ChatModelRunResult | undefined;
164
+ for await (update of asAsyncIterable(stream)) {
165
+ yield update;
166
+ }
102
167
 
103
- if (update === undefined)
104
- throw new Error("No data received from Edge Runtime");
168
+ if (update === undefined)
169
+ throw new Error("No data received from Edge Runtime");
170
+
171
+ this.options.onFinish?.(unstable_getMessage());
172
+ } catch (error: unknown) {
173
+ this.options.onError?.(error as Error);
174
+ throw error;
175
+ }
105
176
  }
106
177
  }
@@ -167,6 +167,10 @@ export class ExternalStoreThreadListRuntimeCore
167
167
  throw new Error("Method not implemented.");
168
168
  }
169
169
 
170
+ public generateTitle(): never {
171
+ throw new Error("Method not implemented.");
172
+ }
173
+
170
174
  private _subscriptions = new Set<() => void>();
171
175
 
172
176
  public subscribe(callback: () => void): Unsubscribe {
@@ -42,6 +42,7 @@ export type ChatModelRunOptions = {
42
42
  readonly config: ModelContext;
43
43
 
44
44
  readonly unstable_assistantMessageId?: string;
45
+ unstable_getMessage(): ThreadMessage;
45
46
  };
46
47
 
47
48
  export type ChatModelAdapter = {
@@ -4,6 +4,7 @@ import { ThreadMessageLike } from "../external-store";
4
4
  import { FeedbackAdapter } from "../adapters/feedback/FeedbackAdapter";
5
5
  import { SpeechSynthesisAdapter } from "../adapters/speech/SpeechAdapterTypes";
6
6
  import { ChatModelAdapter } from "./ChatModelAdapter";
7
+ import { AssistantCloud } from "../../cloud";
7
8
 
8
9
  export type LocalRuntimeOptionsBase = {
9
10
  maxSteps?: number | undefined;
@@ -24,6 +25,7 @@ export type LocalRuntimeOptionsBase = {
24
25
 
25
26
  // TODO align LocalRuntimeOptions with LocalRuntimeOptionsBase
26
27
  export type LocalRuntimeOptions = Omit<LocalRuntimeOptionsBase, "adapters"> & {
28
+ cloud?: AssistantCloud | undefined;
27
29
  initialMessages?: readonly ThreadMessageLike[] | undefined;
28
30
  adapters?: Omit<LocalRuntimeOptionsBase["adapters"], "chatModel"> | undefined;
29
31
  };
@@ -32,6 +34,7 @@ export const splitLocalRuntimeOptions = <T extends LocalRuntimeOptions>(
32
34
  options: T,
33
35
  ) => {
34
36
  const {
37
+ cloud,
35
38
  initialMessages,
36
39
  maxSteps,
37
40
  adapters,
@@ -41,6 +44,7 @@ export const splitLocalRuntimeOptions = <T extends LocalRuntimeOptions>(
41
44
 
42
45
  return {
43
46
  localRuntimeOptions: {
47
+ cloud,
44
48
  initialMessages,
45
49
  maxSteps,
46
50
  adapters,
@@ -1,235 +1,92 @@
1
- import type { Unsubscribe } from "../../types";
2
1
  import { ThreadListRuntimeCore } from "../core/ThreadListRuntimeCore";
3
- import { generateId } from "../../utils/idUtils";
2
+ import { BaseSubscribable } from "../remote-thread-list/BaseSubscribable";
4
3
  import { LocalThreadRuntimeCore } from "./LocalThreadRuntimeCore";
5
4
 
6
- export type ThreadListAdapter = {
7
- subscribe(callback: () => void): Unsubscribe;
8
- };
9
-
10
- export type LocalThreadData = {
11
- readonly runtime: LocalThreadRuntimeCore;
12
- readonly status: "new" | "regular" | "archived";
13
- readonly threadId: string;
14
- readonly title?: string | undefined;
15
- };
16
-
17
5
  export type LocalThreadFactory = () => LocalThreadRuntimeCore;
18
6
 
19
- const RESOLVED_PROMISE = Promise.resolve();
20
- export class LocalThreadListRuntimeCore implements ThreadListRuntimeCore {
21
- private _threadData = new Map<string, LocalThreadData>();
22
- private _threadIds: readonly string[] = [];
23
- private _archivedThreadIds: readonly string[] = [];
24
- private _newThreadId: string | undefined;
7
+ const EMPTY_ARRAY = Object.freeze([]);
8
+ export class LocalThreadListRuntimeCore
9
+ extends BaseSubscribable
10
+ implements ThreadListRuntimeCore
11
+ {
12
+ private _mainThread: LocalThreadRuntimeCore;
13
+ constructor(_threadFactory: LocalThreadFactory) {
14
+ super();
25
15
 
26
- public get newThreadId() {
27
- return this._newThreadId;
16
+ this._mainThread = _threadFactory();
28
17
  }
29
18
 
30
- public get threadIds() {
31
- return this._threadIds;
19
+ public getMainThreadRuntimeCore() {
20
+ return this._mainThread;
32
21
  }
33
22
 
34
- public get archivedThreadIds() {
35
- return this._archivedThreadIds;
23
+ public get newThreadId(): string {
24
+ throw new Error("Method not implemented.");
36
25
  }
37
26
 
38
- private _mainThreadId!: string;
39
-
40
- public get mainThreadId(): string {
41
- return this._mainThreadId;
27
+ public get threadIds(): readonly string[] {
28
+ throw EMPTY_ARRAY;
42
29
  }
43
30
 
44
- constructor(private _threadFactory: LocalThreadFactory) {
45
- this.switchToNewThread();
31
+ public get archivedThreadIds(): readonly string[] {
32
+ throw EMPTY_ARRAY;
46
33
  }
47
34
 
48
- public getMainThreadRuntimeCore() {
49
- const result = this._threadData.get(this._mainThreadId)?.runtime;
50
- if (!result)
51
- throw new Error("Main thread not found. This is a bug in assistant-ui.");
52
- return result;
35
+ public get mainThreadId(): string {
36
+ return "__DEFAULT_ID__";
53
37
  }
54
38
 
55
- public getThreadRuntimeCore(threadId: string) {
56
- const result = this._threadData.get(threadId)?.runtime;
57
- if (!result) throw new Error("Thread not found.");
58
- return result;
39
+ public getThreadRuntimeCore(): never {
40
+ throw new Error("Method not implemented.");
59
41
  }
60
42
 
61
43
  public getLoadThreadsPromise(): Promise<void> {
62
- return RESOLVED_PROMISE;
44
+ throw new Error("Method not implemented.");
63
45
  }
64
46
 
65
47
  public getItemById(threadId: string) {
66
- return this._threadData.get(threadId);
48
+ if (threadId === this.mainThreadId) {
49
+ return {
50
+ status: "regular" as const,
51
+ threadId: this.mainThreadId,
52
+ remoteId: this.mainThreadId,
53
+ externalId: undefined,
54
+ title: undefined,
55
+ isMain: true,
56
+ };
57
+ }
58
+ throw new Error("Method not implemented");
67
59
  }
68
60
 
69
- public async switchToThread(threadId: string): Promise<void> {
70
- if (this._mainThreadId === threadId) return;
71
-
72
- const data = this._threadData.get(threadId);
73
- if (!data) throw new Error("Thread not found");
74
-
75
- if (data.status === "archived") await this.unarchive(threadId);
76
-
77
- this._mainThreadId = data.threadId;
78
- this._notifySubscribers();
61
+ public async switchToThread(): Promise<void> {
62
+ throw new Error("Method not implemented.");
79
63
  }
80
64
 
81
65
  public switchToNewThread(): Promise<void> {
82
- if (this._newThreadId === undefined) {
83
- let threadId: string;
84
- do {
85
- threadId = generateId();
86
- } while (this._threadData.has(threadId));
87
-
88
- const runtime = this._threadFactory();
89
- const dispose = runtime.unstable_on("initialize", () => {
90
- dispose();
91
- const data = this._threadData.get(threadId);
92
- if (!data) throw new Error("Thread not found");
93
-
94
- this._stateOp(threadId, "regular");
95
- });
96
- this._threadData.set(threadId, {
97
- runtime,
98
- status: "new",
99
- threadId,
100
- });
101
- this._newThreadId = threadId;
102
- }
103
-
104
- this.switchToThread(this._newThreadId);
105
- return Promise.resolve();
106
- }
107
-
108
- private async _stateOp(
109
- threadId: string,
110
- newState: "regular" | "archived" | "deleted",
111
- ) {
112
- const data = this._threadData.get(threadId);
113
- if (!data) throw new Error("Thread not found");
114
-
115
- const { status: lastState } = data;
116
- if (lastState === newState) return;
117
-
118
- // lastState
119
- switch (lastState) {
120
- case "new":
121
- this._newThreadId = undefined;
122
- break;
123
- case "regular":
124
- this._threadIds = this._threadIds.filter((t) => t !== threadId);
125
- break;
126
- case "archived":
127
- this._archivedThreadIds = this._archivedThreadIds.filter(
128
- (t) => t !== threadId,
129
- );
130
- break;
131
-
132
- default: {
133
- const _exhaustiveCheck: never = lastState;
134
- throw new Error(`Unsupported state: ${_exhaustiveCheck}`);
135
- }
136
- }
137
-
138
- // newState
139
- switch (newState) {
140
- case "regular":
141
- this._threadIds = [data.threadId, ...this._threadIds];
142
- break;
143
-
144
- case "archived":
145
- this._archivedThreadIds = [data.threadId, ...this._archivedThreadIds];
146
- break;
147
-
148
- case "deleted":
149
- this._threadData.delete(threadId);
150
- break;
151
-
152
- default: {
153
- const _exhaustiveCheck: never = newState;
154
- throw new Error(`Unsupported state: ${_exhaustiveCheck}`);
155
- }
156
- }
157
-
158
- if (newState !== "deleted") {
159
- this._threadData.set(threadId, {
160
- ...data,
161
- status: newState,
162
- });
163
- }
164
-
165
- if (
166
- threadId === this._mainThreadId &&
167
- (newState === "archived" || newState === "deleted")
168
- ) {
169
- const lastThreadId = this._threadIds[0];
170
- if (lastThreadId) {
171
- await this.switchToThread(lastThreadId);
172
- } else {
173
- await this.switchToNewThread();
174
- }
175
- } else {
176
- this._notifySubscribers();
177
- }
66
+ throw new Error("Method not implemented.");
178
67
  }
179
68
 
180
- public rename(threadId: string, newTitle: string): Promise<void> {
181
- const data = this._threadData.get(threadId);
182
- if (!data) throw new Error("Thread not found");
183
-
184
- this._threadData.set(threadId, {
185
- ...data,
186
- title: newTitle,
187
- });
188
- this._notifySubscribers();
189
- return Promise.resolve();
69
+ public rename(): Promise<void> {
70
+ throw new Error("Method not implemented.");
190
71
  }
191
72
 
192
- public archive(threadId: string): Promise<void> {
193
- const data = this._threadData.get(threadId);
194
- if (!data) throw new Error("Thread not found");
195
- if (data.status !== "regular")
196
- throw new Error("Thread is not yet initialized or already archived");
197
-
198
- this._stateOp(threadId, "archived");
199
- return Promise.resolve();
73
+ public archive(): Promise<void> {
74
+ throw new Error("Method not implemented.");
200
75
  }
201
76
 
202
- public unarchive(threadId: string): Promise<void> {
203
- const data = this._threadData.get(threadId);
204
- if (!data) throw new Error("Thread not found");
205
- if (data.status !== "archived") throw new Error("Thread is not archived");
206
-
207
- this._stateOp(threadId, "regular");
208
- return Promise.resolve();
77
+ public unarchive(): Promise<void> {
78
+ throw new Error("Method not implemented.");
209
79
  }
210
80
 
211
- public delete(threadId: string): Promise<void> {
212
- const data = this._threadData.get(threadId);
213
- if (!data) throw new Error("Thread not found");
214
- if (data.status !== "regular" && data.status !== "archived")
215
- throw new Error("Thread is not yet initialized");
216
-
217
- this._stateOp(threadId, "deleted");
218
- return Promise.resolve();
81
+ public delete(): Promise<void> {
82
+ throw new Error("Method not implemented.");
219
83
  }
220
84
 
221
85
  public initialize(): never {
222
86
  throw new Error("Method not implemented.");
223
87
  }
224
88
 
225
- private _subscriptions = new Set<() => void>();
226
-
227
- public subscribe(callback: () => void): Unsubscribe {
228
- this._subscriptions.add(callback);
229
- return () => this._subscriptions.delete(callback);
230
- }
231
-
232
- private _notifySubscribers() {
233
- for (const callback of this._subscriptions) callback();
89
+ public generateTitle(): never {
90
+ throw new Error("Method not implemented.");
234
91
  }
235
92
  }
@@ -249,6 +249,9 @@ export class LocalThreadRuntimeCore
249
249
  context,
250
250
  config: context,
251
251
  unstable_assistantMessageId: message.id,
252
+ unstable_getMessage() {
253
+ return message;
254
+ },
252
255
  });
253
256
 
254
257
  // handle async iterator for streaming results
@@ -10,6 +10,8 @@ import {
10
10
  } from "../../api/AssistantRuntime";
11
11
  import { ThreadRuntimeImpl } from "../../internal";
12
12
  import { useRuntimeAdapters } from "../adapters/RuntimeAdapterProvider";
13
+ import { useRemoteThreadListRuntime } from "../remote-thread-list/useRemoteThreadListRuntime";
14
+ import { useCloudThreadListAdapter } from "../remote-thread-list/adapter/cloud";
13
15
 
14
16
  export type LocalRuntime = AssistantRuntime & {
15
17
  reset: (options?: Parameters<LocalRuntimeCore["reset"]>[0]) => void;
@@ -34,9 +36,9 @@ class LocalRuntimeImpl extends AssistantRuntimeImpl implements LocalRuntime {
34
36
  }
35
37
  }
36
38
 
37
- export const useLocalRuntime = (
39
+ const useLocalThreadRuntime = (
38
40
  adapter: ChatModelAdapter,
39
- { initialMessages, ...options }: LocalRuntimeOptions = {},
41
+ { initialMessages, ...options }: LocalRuntimeOptions,
40
42
  ) => {
41
43
  const { modelContext, ...threadListAdapters } = useRuntimeAdapters() ?? {};
42
44
  const opt = useMemo(
@@ -65,3 +67,14 @@ export const useLocalRuntime = (
65
67
 
66
68
  return useMemo(() => LocalRuntimeImpl.create(runtime), [runtime]);
67
69
  };
70
+
71
+ export const useLocalRuntime = (
72
+ adapter: ChatModelAdapter,
73
+ { cloud, ...options }: LocalRuntimeOptions = {},
74
+ ) => {
75
+ const cloudAdapter = useCloudThreadListAdapter({ cloud });
76
+ return useRemoteThreadListRuntime({
77
+ runtimeHook: () => useLocalThreadRuntime(adapter, options),
78
+ adapter: cloudAdapter,
79
+ });
80
+ };
@@ -121,6 +121,13 @@ export class RemoteThreadListHookInstanceManager extends BaseSubscribable {
121
121
  return runtime.threads.main.unstable_on("initialize", () => {
122
122
  if (threadListItemRuntime.getState().status === "new") {
123
123
  threadListItemRuntime.initialize();
124
+
125
+ // auto generate a title after first run
126
+ const dispose = runtime.thread.unstable_on("run-end", () => {
127
+ dispose();
128
+
129
+ threadListItemRuntime.generateTitle();
130
+ });
124
131
  }
125
132
  });
126
133
  }, [runtime, threadListItemRuntime]);