@assistant-ui/core 0.1.1 → 0.1.3

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.
Files changed (110) hide show
  1. package/dist/model-context/frame/provider.d.ts.map +1 -1
  2. package/dist/model-context/frame/provider.js +2 -4
  3. package/dist/model-context/frame/provider.js.map +1 -1
  4. package/dist/react/RuntimeAdapter.js +4 -1
  5. package/dist/react/RuntimeAdapter.js.map +1 -1
  6. package/dist/react/index.d.ts +2 -1
  7. package/dist/react/index.d.ts.map +1 -1
  8. package/dist/react/index.js +2 -1
  9. package/dist/react/index.js.map +1 -1
  10. package/dist/react/model-context/toolbox.d.ts +7 -1
  11. package/dist/react/model-context/toolbox.d.ts.map +1 -1
  12. package/dist/react/runtimes/RemoteThreadListHookInstanceManager.d.ts +97 -0
  13. package/dist/react/runtimes/RemoteThreadListHookInstanceManager.d.ts.map +1 -0
  14. package/dist/react/runtimes/RemoteThreadListHookInstanceManager.js +111 -0
  15. package/dist/react/runtimes/RemoteThreadListHookInstanceManager.js.map +1 -0
  16. package/dist/react/runtimes/RemoteThreadListThreadListRuntimeCore.d.ts +115 -0
  17. package/dist/react/runtimes/RemoteThreadListThreadListRuntimeCore.d.ts.map +1 -0
  18. package/dist/react/runtimes/RemoteThreadListThreadListRuntimeCore.js +444 -0
  19. package/dist/react/runtimes/RemoteThreadListThreadListRuntimeCore.js.map +1 -0
  20. package/dist/react/runtimes/RuntimeAdapterProvider.d.ts +18 -0
  21. package/dist/react/runtimes/RuntimeAdapterProvider.d.ts.map +1 -0
  22. package/dist/react/runtimes/RuntimeAdapterProvider.js +14 -0
  23. package/dist/react/runtimes/RuntimeAdapterProvider.js.map +1 -0
  24. package/dist/react/runtimes/cloud/AssistantCloudThreadHistoryAdapter.d.ts +5 -0
  25. package/dist/react/runtimes/cloud/AssistantCloudThreadHistoryAdapter.d.ts.map +1 -0
  26. package/dist/react/runtimes/cloud/AssistantCloudThreadHistoryAdapter.js +528 -0
  27. package/dist/react/runtimes/cloud/AssistantCloudThreadHistoryAdapter.js.map +1 -0
  28. package/dist/react/runtimes/cloud/CloudFileAttachmentAdapter.d.ts +15 -0
  29. package/dist/react/runtimes/cloud/CloudFileAttachmentAdapter.d.ts.map +1 -0
  30. package/dist/react/runtimes/cloud/CloudFileAttachmentAdapter.js +83 -0
  31. package/dist/react/runtimes/cloud/CloudFileAttachmentAdapter.js.map +1 -0
  32. package/dist/react/runtimes/cloud/auiV0.d.ts +62 -0
  33. package/dist/react/runtimes/cloud/auiV0.d.ts.map +1 -0
  34. package/dist/react/runtimes/cloud/auiV0.js +74 -0
  35. package/dist/react/runtimes/cloud/auiV0.js.map +1 -0
  36. package/dist/react/runtimes/cloud/index.d.ts +4 -0
  37. package/dist/react/runtimes/cloud/index.d.ts.map +1 -0
  38. package/dist/react/runtimes/cloud/index.js +4 -0
  39. package/dist/react/runtimes/cloud/index.js.map +1 -0
  40. package/dist/react/runtimes/cloud/useCloudThreadListAdapter.d.ts +13 -0
  41. package/dist/react/runtimes/cloud/useCloudThreadListAdapter.d.ts.map +1 -0
  42. package/dist/react/runtimes/cloud/useCloudThreadListAdapter.js +102 -0
  43. package/dist/react/runtimes/cloud/useCloudThreadListAdapter.js.map +1 -0
  44. package/dist/react/runtimes/createMessageConverter.d.ts +17 -0
  45. package/dist/react/runtimes/createMessageConverter.d.ts.map +1 -0
  46. package/dist/react/runtimes/createMessageConverter.js +50 -0
  47. package/dist/react/runtimes/createMessageConverter.js.map +1 -0
  48. package/dist/react/runtimes/external-message-converter.d.ts +34 -0
  49. package/dist/react/runtimes/external-message-converter.d.ts.map +1 -0
  50. package/dist/react/runtimes/external-message-converter.js +309 -0
  51. package/dist/react/runtimes/external-message-converter.js.map +1 -0
  52. package/dist/react/runtimes/index.d.ts +10 -0
  53. package/dist/react/runtimes/index.d.ts.map +1 -0
  54. package/dist/react/runtimes/index.js +10 -0
  55. package/dist/react/runtimes/index.js.map +1 -0
  56. package/dist/react/runtimes/useExternalStoreRuntime.d.ts +4 -0
  57. package/dist/react/runtimes/useExternalStoreRuntime.d.ts.map +1 -0
  58. package/dist/react/runtimes/useExternalStoreRuntime.js +19 -0
  59. package/dist/react/runtimes/useExternalStoreRuntime.js.map +1 -0
  60. package/dist/react/runtimes/useRemoteThreadListRuntime.d.ts +4 -0
  61. package/dist/react/runtimes/useRemoteThreadListRuntime.d.ts.map +1 -0
  62. package/dist/react/runtimes/useRemoteThreadListRuntime.js +48 -0
  63. package/dist/react/runtimes/useRemoteThreadListRuntime.js.map +1 -0
  64. package/dist/react/runtimes/useToolInvocations.d.ts +38 -0
  65. package/dist/react/runtimes/useToolInvocations.d.ts.map +1 -0
  66. package/dist/react/runtimes/useToolInvocations.js +411 -0
  67. package/dist/react/runtimes/useToolInvocations.js.map +1 -0
  68. package/dist/react/types/store-augmentation.d.ts +0 -1
  69. package/dist/react/types/store-augmentation.d.ts.map +1 -1
  70. package/dist/react/types/store-augmentation.js +1 -1
  71. package/dist/react/types/store-augmentation.js.map +1 -1
  72. package/dist/runtime/base/base-composer-runtime-core.d.ts.map +1 -1
  73. package/dist/runtime/base/base-composer-runtime-core.js +2 -0
  74. package/dist/runtime/base/base-composer-runtime-core.js.map +1 -1
  75. package/dist/store/index.d.ts +1 -1
  76. package/dist/store/index.d.ts.map +1 -1
  77. package/dist/store/index.js +1 -2
  78. package/dist/store/index.js.map +1 -1
  79. package/dist/utils/json/is-json-equal.d.ts +2 -0
  80. package/dist/utils/json/is-json-equal.d.ts.map +1 -0
  81. package/dist/utils/json/is-json-equal.js +31 -0
  82. package/dist/utils/json/is-json-equal.js.map +1 -0
  83. package/dist/utils/json/is-json.d.ts +6 -0
  84. package/dist/utils/json/is-json.d.ts.map +1 -0
  85. package/dist/utils/json/is-json.js +33 -0
  86. package/dist/utils/json/is-json.js.map +1 -0
  87. package/package.json +10 -9
  88. package/src/model-context/frame/provider.ts +2 -6
  89. package/src/react/RuntimeAdapter.ts +5 -1
  90. package/src/react/index.ts +2 -1
  91. package/src/react/model-context/toolbox.ts +7 -3
  92. package/src/react/runtimes/RemoteThreadListHookInstanceManager.tsx +176 -0
  93. package/src/react/runtimes/RemoteThreadListThreadListRuntimeCore.tsx +534 -0
  94. package/src/react/runtimes/RuntimeAdapterProvider.tsx +40 -0
  95. package/src/react/runtimes/cloud/AssistantCloudThreadHistoryAdapter.ts +785 -0
  96. package/src/react/runtimes/cloud/CloudFileAttachmentAdapter.ts +101 -0
  97. package/src/react/runtimes/cloud/auiV0.ts +160 -0
  98. package/src/react/runtimes/cloud/index.ts +3 -0
  99. package/src/react/runtimes/cloud/useCloudThreadListAdapter.tsx +152 -0
  100. package/src/react/runtimes/createMessageConverter.ts +77 -0
  101. package/src/react/runtimes/external-message-converter.ts +487 -0
  102. package/src/react/runtimes/index.ts +30 -0
  103. package/src/react/runtimes/useExternalStoreRuntime.ts +27 -0
  104. package/src/react/runtimes/useRemoteThreadListRuntime.ts +76 -0
  105. package/src/react/runtimes/useToolInvocations.ts +594 -0
  106. package/src/react/types/store-augmentation.ts +0 -2
  107. package/src/runtime/base/base-composer-runtime-core.ts +2 -0
  108. package/src/store/index.ts +1 -2
  109. package/src/utils/json/is-json-equal.ts +48 -0
  110. package/src/utils/json/is-json.ts +58 -0
@@ -0,0 +1,101 @@
1
+ import type { AssistantCloud } from "assistant-cloud";
2
+ import type {
3
+ Attachment,
4
+ PendingAttachment,
5
+ CompleteAttachment,
6
+ ThreadUserMessagePart,
7
+ } from "../../../types";
8
+ import type { AttachmentAdapter } from "../../../adapters/attachment";
9
+
10
+ const guessAttachmentType = (
11
+ contentType: string,
12
+ ): "image" | "document" | "file" => {
13
+ if (contentType.startsWith("image/")) return "image";
14
+ if (contentType.startsWith("text/")) return "document";
15
+ return "file";
16
+ };
17
+
18
+ export class CloudFileAttachmentAdapter implements AttachmentAdapter {
19
+ public accept = "*";
20
+
21
+ constructor(private cloud: AssistantCloud) {}
22
+
23
+ private uploadedUrls = new Map<string, string>();
24
+
25
+ public async *add({
26
+ file,
27
+ }: {
28
+ file: File;
29
+ }): AsyncGenerator<PendingAttachment, void> {
30
+ const id = crypto.randomUUID();
31
+ const type = guessAttachmentType(file.type);
32
+ let attachment: PendingAttachment = {
33
+ id,
34
+ type,
35
+ name: file.name,
36
+ contentType: file.type,
37
+ file,
38
+ status: { type: "running", reason: "uploading", progress: 0 },
39
+ };
40
+ yield attachment;
41
+
42
+ try {
43
+ const { signedUrl, publicUrl } =
44
+ await this.cloud.files.generatePresignedUploadUrl({
45
+ filename: file.name,
46
+ });
47
+ await fetch(signedUrl, {
48
+ method: "PUT",
49
+ body: file,
50
+ headers: {
51
+ "Content-Type": file.type,
52
+ },
53
+ mode: "cors",
54
+ });
55
+ this.uploadedUrls.set(id, publicUrl);
56
+ attachment = {
57
+ ...attachment,
58
+ status: { type: "requires-action", reason: "composer-send" },
59
+ };
60
+ yield attachment;
61
+ } catch {
62
+ attachment = {
63
+ ...attachment,
64
+ status: { type: "incomplete", reason: "error" },
65
+ };
66
+ yield attachment;
67
+ }
68
+ }
69
+
70
+ public async remove(attachment: Attachment): Promise<void> {
71
+ this.uploadedUrls.delete(attachment.id);
72
+ }
73
+
74
+ public async send(
75
+ attachment: PendingAttachment,
76
+ ): Promise<CompleteAttachment> {
77
+ const url = this.uploadedUrls.get(attachment.id);
78
+ if (!url) throw new Error("Attachment not uploaded");
79
+ this.uploadedUrls.delete(attachment.id);
80
+
81
+ let content: ThreadUserMessagePart[];
82
+ if (attachment.type === "image") {
83
+ content = [{ type: "image", image: url, filename: attachment.name }];
84
+ } else {
85
+ content = [
86
+ {
87
+ type: "file",
88
+ data: url,
89
+ mimeType: attachment.contentType ?? "",
90
+ filename: attachment.name,
91
+ },
92
+ ];
93
+ }
94
+
95
+ return {
96
+ ...attachment,
97
+ status: { type: "complete" },
98
+ content,
99
+ };
100
+ }
101
+ }
@@ -0,0 +1,160 @@
1
+ import type { MessageStatus, ThreadMessage } from "../../../types";
2
+ import { fromThreadMessageLike } from "../../../runtime/utils/thread-message-like";
3
+ import { CloudMessage } from "assistant-cloud";
4
+ import { isJSONValue } from "../../../utils/json/is-json";
5
+ import { ReadonlyJSONObject, ReadonlyJSONValue } from "assistant-stream/utils";
6
+ import type { ExportedMessageRepositoryItem } from "../../../runtime/utils/message-repository";
7
+
8
+ type AuiV0MessagePart =
9
+ | {
10
+ readonly type: "text";
11
+ readonly text: string;
12
+ }
13
+ | {
14
+ readonly type: "reasoning";
15
+ readonly text: string;
16
+ }
17
+ | {
18
+ readonly type: "source";
19
+ readonly sourceType: "url";
20
+ readonly id: string;
21
+ readonly url: string;
22
+ readonly title?: string;
23
+ }
24
+ | {
25
+ readonly type: "tool-call";
26
+ readonly toolCallId: string;
27
+ readonly toolName: string;
28
+ readonly args: ReadonlyJSONObject;
29
+ readonly result?: ReadonlyJSONValue;
30
+ readonly isError?: true;
31
+ }
32
+ | {
33
+ readonly type: "tool-call";
34
+ readonly toolCallId: string;
35
+ readonly toolName: string;
36
+ readonly argsText: string;
37
+ readonly result?: ReadonlyJSONValue;
38
+ readonly isError?: true;
39
+ }
40
+ | {
41
+ readonly type: "image";
42
+ readonly image: string;
43
+ }
44
+ | {
45
+ readonly type: "file";
46
+ readonly data: string;
47
+ readonly mimeType: string;
48
+ readonly filename?: string;
49
+ };
50
+
51
+ type AuiV0Message = {
52
+ readonly role: "assistant" | "user" | "system";
53
+ readonly status?: MessageStatus;
54
+ readonly content: readonly AuiV0MessagePart[];
55
+ readonly metadata: {
56
+ readonly unstable_state?: ReadonlyJSONValue;
57
+ readonly unstable_annotations: readonly ReadonlyJSONValue[];
58
+ readonly unstable_data: readonly ReadonlyJSONValue[];
59
+ readonly steps: readonly {
60
+ readonly usage?: {
61
+ readonly inputTokens: number;
62
+ readonly outputTokens: number;
63
+ };
64
+ }[];
65
+ readonly custom: ReadonlyJSONObject;
66
+ };
67
+ };
68
+
69
+ export function auiV0Encode(message: ThreadMessage): AuiV0Message {
70
+ // TODO attachments are currently intentionally ignored
71
+ // info: ID and createdAt are ignored (we use the server value instead)
72
+
73
+ const status: MessageStatus | undefined =
74
+ message.status?.type === "running"
75
+ ? { type: "incomplete", reason: "cancelled" }
76
+ : message.status;
77
+
78
+ return {
79
+ role: message.role,
80
+ content: message.content.map((part) => {
81
+ const type = part.type;
82
+ switch (type) {
83
+ case "text":
84
+ return { type: "text", text: part.text };
85
+
86
+ case "reasoning":
87
+ return { type: "reasoning", text: part.text };
88
+
89
+ case "source":
90
+ return {
91
+ type: "source",
92
+ sourceType: part.sourceType,
93
+ id: part.id,
94
+ url: part.url,
95
+ ...(part.title ? { title: part.title } : undefined),
96
+ };
97
+
98
+ case "tool-call": {
99
+ if (!isJSONValue(part.result)) {
100
+ console.warn(
101
+ `tool-call result is not JSON! ${JSON.stringify(part)}`,
102
+ );
103
+ }
104
+ return {
105
+ type: "tool-call",
106
+ toolCallId: part.toolCallId,
107
+ toolName: part.toolName,
108
+ ...(JSON.stringify(part.args) === part.argsText
109
+ ? { args: part.args }
110
+ : { argsText: part.argsText }),
111
+ ...(part.result
112
+ ? { result: part.result as ReadonlyJSONValue }
113
+ : undefined),
114
+ ...(part.isError ? { isError: true } : undefined),
115
+ };
116
+ }
117
+
118
+ case "image":
119
+ return { type: "image", image: part.image };
120
+
121
+ case "file":
122
+ return {
123
+ type: "file",
124
+ data: part.data,
125
+ mimeType: part.mimeType,
126
+ ...(part.filename ? { filename: part.filename } : undefined),
127
+ };
128
+
129
+ default: {
130
+ const unhandledType: "audio" | "data" = type;
131
+ throw new Error(
132
+ `Message part type not supported by aui/v0: ${unhandledType}`,
133
+ );
134
+ }
135
+ }
136
+ }),
137
+ metadata: message.metadata as AuiV0Message["metadata"],
138
+ ...(status ? { status } : undefined),
139
+ };
140
+ }
141
+
142
+ export function auiV0Decode(
143
+ cloudMessage: CloudMessage & { format: "aui/v0" },
144
+ ): ExportedMessageRepositoryItem {
145
+ const payload = cloudMessage.content as unknown as AuiV0Message;
146
+ const message = fromThreadMessageLike(
147
+ {
148
+ id: cloudMessage.id,
149
+ createdAt: cloudMessage.created_at,
150
+ ...payload,
151
+ },
152
+ cloudMessage.id,
153
+ { type: "complete", reason: "unknown" },
154
+ );
155
+
156
+ return {
157
+ parentId: cloudMessage.parent_id,
158
+ message,
159
+ };
160
+ }
@@ -0,0 +1,3 @@
1
+ export { useCloudThreadListAdapter } from "./useCloudThreadListAdapter";
2
+ export { useAssistantCloudThreadHistoryAdapter } from "./AssistantCloudThreadHistoryAdapter";
3
+ export { CloudFileAttachmentAdapter } from "./CloudFileAttachmentAdapter";
@@ -0,0 +1,152 @@
1
+ declare const process: { env: Record<string, string | undefined> };
2
+
3
+ import {
4
+ FC,
5
+ PropsWithChildren,
6
+ useCallback,
7
+ useEffect,
8
+ useMemo,
9
+ useRef,
10
+ } from "react";
11
+ import { AssistantCloud } from "assistant-cloud";
12
+ import type { RemoteThreadListAdapter } from "../../../runtimes/remote-thread-list/types";
13
+ import { InMemoryThreadListAdapter } from "../../../runtimes/remote-thread-list/adapter/in-memory";
14
+ import { useAssistantCloudThreadHistoryAdapter } from "./AssistantCloudThreadHistoryAdapter";
15
+ import { RuntimeAdapterProvider } from "../RuntimeAdapterProvider";
16
+ import { CloudFileAttachmentAdapter } from "./CloudFileAttachmentAdapter";
17
+
18
+ type ThreadData = {
19
+ externalId: string | undefined;
20
+ };
21
+
22
+ type CloudThreadListAdapterOptions = {
23
+ cloud?: AssistantCloud | undefined;
24
+
25
+ create?: (() => Promise<ThreadData>) | undefined;
26
+ delete?: ((threadId: string) => Promise<void>) | undefined;
27
+ };
28
+
29
+ const baseUrl = process?.env?.["NEXT_PUBLIC_ASSISTANT_BASE_URL"];
30
+ const autoCloud = baseUrl
31
+ ? new AssistantCloud({ baseUrl, anonymous: true })
32
+ : undefined;
33
+
34
+ export const useCloudThreadListAdapter = (
35
+ adapter: CloudThreadListAdapterOptions,
36
+ ): RemoteThreadListAdapter => {
37
+ const adapterRef = useRef(adapter);
38
+ useEffect(() => {
39
+ adapterRef.current = adapter;
40
+ }, [adapter]);
41
+
42
+ const unstable_Provider = useCallback<FC<PropsWithChildren>>(
43
+ function Provider({ children }) {
44
+ const history = useAssistantCloudThreadHistoryAdapter({
45
+ get current() {
46
+ return adapterRef.current.cloud ?? autoCloud!;
47
+ },
48
+ });
49
+ const cloudInstance = adapterRef.current.cloud ?? autoCloud!;
50
+ const attachments = useMemo(
51
+ () => new CloudFileAttachmentAdapter(cloudInstance),
52
+ [cloudInstance],
53
+ );
54
+
55
+ const adapters = useMemo(
56
+ () => ({
57
+ history,
58
+ attachments,
59
+ }),
60
+ [history, attachments],
61
+ );
62
+
63
+ return (
64
+ <RuntimeAdapterProvider adapters={adapters}>
65
+ {children}
66
+ </RuntimeAdapterProvider>
67
+ );
68
+ },
69
+ [],
70
+ );
71
+
72
+ const cloud = adapter.cloud ?? autoCloud;
73
+ if (!cloud) {
74
+ const ref = adapterRef;
75
+ const inMemory = new InMemoryThreadListAdapter();
76
+ inMemory.initialize = async (threadId: string) => {
77
+ const result = await ref.current.create?.();
78
+ return { remoteId: threadId, externalId: result?.externalId };
79
+ };
80
+ return inMemory;
81
+ }
82
+
83
+ return {
84
+ list: async () => {
85
+ const { threads } = await cloud.threads.list();
86
+ return {
87
+ threads: threads.map((t) => ({
88
+ status: t.is_archived ? "archived" : "regular",
89
+ remoteId: t.id,
90
+ title: t.title,
91
+ externalId: t.external_id ?? undefined,
92
+ })),
93
+ };
94
+ },
95
+
96
+ initialize: async () => {
97
+ const createTask = adapter.create?.() ?? Promise.resolve();
98
+ const t = await createTask;
99
+ const external_id = t ? t.externalId : undefined;
100
+ const { thread_id: remoteId } = await cloud.threads.create({
101
+ last_message_at: new Date(),
102
+ external_id,
103
+ });
104
+
105
+ return { externalId: external_id, remoteId: remoteId };
106
+ },
107
+
108
+ rename: async (threadId, newTitle) => {
109
+ return cloud.threads.update(threadId, { title: newTitle });
110
+ },
111
+ archive: async (threadId) => {
112
+ return cloud.threads.update(threadId, { is_archived: true });
113
+ },
114
+ unarchive: async (threadId) => {
115
+ return cloud.threads.update(threadId, { is_archived: false });
116
+ },
117
+ delete: async (threadId) => {
118
+ await adapter.delete?.(threadId);
119
+ return cloud.threads.delete(threadId);
120
+ },
121
+
122
+ generateTitle: async (threadId, messages) => {
123
+ // Filter messages to only include content types the title generator understands
124
+ // (reasoning, source, etc. are not needed for title generation)
125
+ // TODO serialize these to a more efficient format
126
+ const filteredMessages = messages.map((msg) => ({
127
+ ...msg,
128
+ content: msg.content.filter(
129
+ (part) => part.type === "text" || part.type === "tool-call",
130
+ ),
131
+ }));
132
+
133
+ return cloud.runs.stream({
134
+ thread_id: threadId,
135
+ assistant_id: "system/thread_title",
136
+ messages: filteredMessages,
137
+ });
138
+ },
139
+
140
+ fetch: async (threadId: string) => {
141
+ const thread = await cloud.threads.get(threadId);
142
+ return {
143
+ status: thread.is_archived ? "archived" : "regular",
144
+ remoteId: thread.id,
145
+ title: thread.title,
146
+ externalId: thread.external_id ?? undefined,
147
+ };
148
+ },
149
+
150
+ unstable_Provider,
151
+ };
152
+ };
@@ -0,0 +1,77 @@
1
+ "use client";
2
+ import type { ThreadMessage } from "../../types";
3
+ import type { ThreadState } from "../../runtime/api/thread-runtime";
4
+ import { useAui, useAuiState } from "@assistant-ui/store";
5
+ import {
6
+ useExternalMessageConverter,
7
+ convertExternalMessages,
8
+ } from "./external-message-converter";
9
+ import { getExternalStoreMessages } from "../../runtime/utils/external-store-message";
10
+
11
+ export const createMessageConverter = <T extends object>(
12
+ callback: useExternalMessageConverter.Callback<T>,
13
+ ) => {
14
+ const result = {
15
+ useThreadMessages: ({
16
+ messages,
17
+ isRunning,
18
+ joinStrategy,
19
+ metadata,
20
+ }: {
21
+ messages: T[];
22
+ isRunning: boolean;
23
+ joinStrategy?: "concat-content" | "none" | undefined;
24
+ metadata?: useExternalMessageConverter.Metadata;
25
+ }) => {
26
+ return useExternalMessageConverter<T>({
27
+ callback,
28
+ messages,
29
+ isRunning,
30
+ joinStrategy,
31
+ metadata,
32
+ });
33
+ },
34
+ toThreadMessages: (
35
+ messages: T[],
36
+ isRunning = false,
37
+ metadata: useExternalMessageConverter.Metadata = {},
38
+ ) => {
39
+ return convertExternalMessages(messages, callback, isRunning, metadata);
40
+ },
41
+ toOriginalMessages: (
42
+ input: ThreadState | ThreadMessage | ThreadMessage["content"][number],
43
+ ) => {
44
+ const messages = getExternalStoreMessages(input);
45
+ if (messages.length === 0) throw new Error("No original messages found");
46
+ return messages;
47
+ },
48
+ toOriginalMessage: (
49
+ input: ThreadState | ThreadMessage | ThreadMessage["content"][number],
50
+ ) => {
51
+ const messages = result.toOriginalMessages(input);
52
+ return messages[0]!;
53
+ },
54
+ useOriginalMessage: () => {
55
+ const messageMessages = result.useOriginalMessages();
56
+ const first = messageMessages[0]!;
57
+ return first;
58
+ },
59
+ useOriginalMessages: () => {
60
+ const aui = useAui();
61
+ const partMessages = useAuiState((s) => {
62
+ if (aui.part.source) return getExternalStoreMessages(s.part);
63
+ return undefined;
64
+ });
65
+
66
+ const messageMessages = useAuiState<T[]>((s) =>
67
+ getExternalStoreMessages(s.message),
68
+ );
69
+
70
+ const messages = partMessages ?? messageMessages;
71
+ if (messages.length === 0) throw new Error("No original messages found");
72
+ return messages;
73
+ },
74
+ };
75
+
76
+ return result;
77
+ };