@assistant-ui/react 0.10.22 → 0.10.24

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 (194) hide show
  1. package/dist/cloud/AssistantCloudThreadHistoryAdapter.d.ts +1 -1
  2. package/dist/cloud/AssistantCloudThreadHistoryAdapter.d.ts.map +1 -1
  3. package/dist/cloud/AssistantCloudThreadHistoryAdapter.js.map +1 -1
  4. package/dist/cloud/auiV0.d.ts +1 -1
  5. package/dist/cloud/auiV0.d.ts.map +1 -1
  6. package/dist/cloud/auiV0.js.map +1 -1
  7. package/dist/cloud/index.d.ts +1 -1
  8. package/dist/cloud/index.d.ts.map +1 -1
  9. package/dist/cloud/index.js +1 -1
  10. package/dist/cloud/index.js.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.map +1 -1
  14. package/dist/context/react/AssistantContext.d.ts +23 -0
  15. package/dist/context/react/AssistantContext.d.ts.map +1 -1
  16. package/dist/context/react/AssistantContext.js.map +1 -1
  17. package/dist/context/react/ComposerContext.d.ts +64 -0
  18. package/dist/context/react/ComposerContext.d.ts.map +1 -1
  19. package/dist/context/react/ComposerContext.js.map +1 -1
  20. package/dist/context/react/MessageContext.d.ts +56 -0
  21. package/dist/context/react/MessageContext.d.ts.map +1 -1
  22. package/dist/context/react/MessageContext.js.map +1 -1
  23. package/dist/context/react/ThreadContext.d.ts +42 -0
  24. package/dist/context/react/ThreadContext.d.ts.map +1 -1
  25. package/dist/context/react/ThreadContext.js.map +1 -1
  26. package/dist/primitives/actionBar/ActionBarCopy.d.ts +42 -0
  27. package/dist/primitives/actionBar/ActionBarCopy.d.ts.map +1 -1
  28. package/dist/primitives/actionBar/ActionBarCopy.js.map +1 -1
  29. package/dist/primitives/actionBar/ActionBarEdit.d.ts +38 -0
  30. package/dist/primitives/actionBar/ActionBarEdit.d.ts.map +1 -1
  31. package/dist/primitives/actionBar/ActionBarEdit.js.map +1 -1
  32. package/dist/primitives/actionBar/ActionBarReload.d.ts +39 -0
  33. package/dist/primitives/actionBar/ActionBarReload.d.ts.map +1 -1
  34. package/dist/primitives/actionBar/ActionBarReload.js.map +1 -1
  35. package/dist/primitives/actionBar/ActionBarRoot.d.ts +56 -0
  36. package/dist/primitives/actionBar/ActionBarRoot.d.ts.map +1 -1
  37. package/dist/primitives/actionBar/ActionBarRoot.js.map +1 -1
  38. package/dist/primitives/attachment/AttachmentRoot.d.ts +18 -0
  39. package/dist/primitives/attachment/AttachmentRoot.d.ts.map +1 -1
  40. package/dist/primitives/attachment/AttachmentRoot.js.map +1 -1
  41. package/dist/primitives/branchPicker/BranchPickerCount.d.ts +17 -0
  42. package/dist/primitives/branchPicker/BranchPickerCount.d.ts.map +1 -1
  43. package/dist/primitives/branchPicker/BranchPickerCount.js.map +1 -1
  44. package/dist/primitives/branchPicker/BranchPickerNext.d.ts +17 -0
  45. package/dist/primitives/branchPicker/BranchPickerNext.d.ts.map +1 -1
  46. package/dist/primitives/branchPicker/BranchPickerNext.js.map +1 -1
  47. package/dist/primitives/branchPicker/BranchPickerPrevious.d.ts +38 -0
  48. package/dist/primitives/branchPicker/BranchPickerPrevious.d.ts.map +1 -1
  49. package/dist/primitives/branchPicker/BranchPickerPrevious.js.map +1 -1
  50. package/dist/primitives/branchPicker/BranchPickerRoot.d.ts +27 -0
  51. package/dist/primitives/branchPicker/BranchPickerRoot.d.ts.map +1 -1
  52. package/dist/primitives/branchPicker/BranchPickerRoot.js.map +1 -1
  53. package/dist/primitives/composer/ComposerAttachments.d.ts.map +1 -1
  54. package/dist/primitives/composer/ComposerAttachments.js +11 -8
  55. package/dist/primitives/composer/ComposerAttachments.js.map +1 -1
  56. package/dist/primitives/composer/ComposerCancel.d.ts +17 -0
  57. package/dist/primitives/composer/ComposerCancel.d.ts.map +1 -1
  58. package/dist/primitives/composer/ComposerCancel.js.map +1 -1
  59. package/dist/primitives/composer/ComposerInput.d.ts +72 -0
  60. package/dist/primitives/composer/ComposerInput.d.ts.map +1 -1
  61. package/dist/primitives/composer/ComposerInput.js.map +1 -1
  62. package/dist/primitives/composer/ComposerRoot.d.ts +19 -0
  63. package/dist/primitives/composer/ComposerRoot.d.ts.map +1 -1
  64. package/dist/primitives/composer/ComposerRoot.js.map +1 -1
  65. package/dist/primitives/composer/ComposerSend.d.ts +18 -0
  66. package/dist/primitives/composer/ComposerSend.d.ts.map +1 -1
  67. package/dist/primitives/composer/ComposerSend.js.map +1 -1
  68. package/dist/primitives/contentPart/ContentPartImage.d.ts +19 -0
  69. package/dist/primitives/contentPart/ContentPartImage.d.ts.map +1 -1
  70. package/dist/primitives/contentPart/ContentPartImage.js.map +1 -1
  71. package/dist/primitives/contentPart/ContentPartText.d.ts +34 -0
  72. package/dist/primitives/contentPart/ContentPartText.d.ts.map +1 -1
  73. package/dist/primitives/contentPart/ContentPartText.js.map +1 -1
  74. package/dist/primitives/message/MessageAttachments.d.ts.map +1 -1
  75. package/dist/primitives/message/MessageAttachments.js +11 -8
  76. package/dist/primitives/message/MessageAttachments.js.map +1 -1
  77. package/dist/primitives/message/MessageContent.d.ts +41 -0
  78. package/dist/primitives/message/MessageContent.d.ts.map +1 -1
  79. package/dist/primitives/message/MessageContent.js +14 -11
  80. package/dist/primitives/message/MessageContent.js.map +1 -1
  81. package/dist/primitives/message/MessageRoot.d.ts +22 -0
  82. package/dist/primitives/message/MessageRoot.d.ts.map +1 -1
  83. package/dist/primitives/message/MessageRoot.js.map +1 -1
  84. package/dist/primitives/thread/ThreadMessages.d.ts +44 -0
  85. package/dist/primitives/thread/ThreadMessages.d.ts.map +1 -1
  86. package/dist/primitives/thread/ThreadMessages.js +5 -2
  87. package/dist/primitives/thread/ThreadMessages.js.map +1 -1
  88. package/dist/primitives/thread/ThreadRoot.d.ts +19 -0
  89. package/dist/primitives/thread/ThreadRoot.d.ts.map +1 -1
  90. package/dist/primitives/thread/ThreadRoot.js.map +1 -1
  91. package/dist/primitives/thread/ThreadViewport.d.ts +24 -0
  92. package/dist/primitives/thread/ThreadViewport.d.ts.map +1 -1
  93. package/dist/primitives/thread/ThreadViewport.js.map +1 -1
  94. package/dist/primitives/threadList/ThreadListItems.d.ts.map +1 -1
  95. package/dist/primitives/threadList/ThreadListItems.js +12 -9
  96. package/dist/primitives/threadList/ThreadListItems.js.map +1 -1
  97. package/dist/runtimes/adapters/attachment/AttachmentAdapter.d.ts +54 -0
  98. package/dist/runtimes/adapters/attachment/AttachmentAdapter.d.ts.map +1 -1
  99. package/dist/runtimes/adapters/feedback/FeedbackAdapter.d.ts +33 -0
  100. package/dist/runtimes/adapters/feedback/FeedbackAdapter.d.ts.map +1 -1
  101. package/dist/runtimes/adapters/speech/SpeechAdapterTypes.d.ts +47 -0
  102. package/dist/runtimes/adapters/speech/SpeechAdapterTypes.d.ts.map +1 -1
  103. package/dist/runtimes/local/LocalRuntimeOptions.d.ts +2 -2
  104. package/dist/runtimes/local/LocalRuntimeOptions.d.ts.map +1 -1
  105. package/dist/runtimes/local/LocalRuntimeOptions.js.map +1 -1
  106. package/dist/runtimes/local/index.d.ts +1 -1
  107. package/dist/runtimes/local/index.d.ts.map +1 -1
  108. package/dist/runtimes/local/index.js +3 -2
  109. package/dist/runtimes/local/index.js.map +1 -1
  110. package/dist/runtimes/remote-thread-list/adapter/cloud.d.ts +1 -1
  111. package/dist/runtimes/remote-thread-list/adapter/cloud.d.ts.map +1 -1
  112. package/dist/runtimes/remote-thread-list/adapter/cloud.js +1 -1
  113. package/dist/runtimes/remote-thread-list/adapter/cloud.js.map +1 -1
  114. package/dist/tests/setup.js +8 -8
  115. package/dist/tests/setup.js.map +1 -1
  116. package/package.json +8 -7
  117. package/src/cloud/AssistantCloudThreadHistoryAdapter.tsx +1 -1
  118. package/src/cloud/auiV0.ts +1 -1
  119. package/src/cloud/index.ts +1 -1
  120. package/src/cloud/useCloudThreadListRuntime.tsx +1 -1
  121. package/src/context/react/AssistantContext.ts +23 -0
  122. package/src/context/react/ComposerContext.ts +64 -0
  123. package/src/context/react/MessageContext.ts +56 -0
  124. package/src/context/react/ThreadContext.ts +42 -0
  125. package/src/primitives/actionBar/ActionBarCopy.tsx +42 -0
  126. package/src/primitives/actionBar/ActionBarEdit.tsx +38 -0
  127. package/src/primitives/actionBar/ActionBarReload.tsx +39 -0
  128. package/src/primitives/actionBar/ActionBarRoot.tsx +38 -0
  129. package/src/primitives/attachment/AttachmentRoot.tsx +18 -0
  130. package/src/primitives/branchPicker/BranchPickerCount.tsx +17 -0
  131. package/src/primitives/branchPicker/BranchPickerNext.tsx +17 -0
  132. package/src/primitives/branchPicker/BranchPickerPrevious.tsx +38 -0
  133. package/src/primitives/branchPicker/BranchPickerRoot.tsx +22 -0
  134. package/src/primitives/composer/ComposerAttachments.tsx +11 -7
  135. package/src/primitives/composer/ComposerCancel.tsx +17 -0
  136. package/src/primitives/composer/ComposerInput.tsx +44 -0
  137. package/src/primitives/composer/ComposerRoot.tsx +19 -0
  138. package/src/primitives/composer/ComposerSend.tsx +18 -0
  139. package/src/primitives/contentPart/ContentPartImage.tsx +19 -0
  140. package/src/primitives/contentPart/ContentPartText.tsx +25 -0
  141. package/src/primitives/message/MessageAttachments.tsx +11 -7
  142. package/src/primitives/message/MessageContent.tsx +54 -18
  143. package/src/primitives/message/MessageRoot.tsx +22 -0
  144. package/src/primitives/thread/ThreadMessages.tsx +52 -4
  145. package/src/primitives/thread/ThreadRoot.tsx +19 -0
  146. package/src/primitives/thread/ThreadViewport.tsx +19 -0
  147. package/src/primitives/threadList/ThreadListItems.tsx +12 -8
  148. package/src/runtimes/adapters/attachment/AttachmentAdapter.ts +56 -0
  149. package/src/runtimes/adapters/feedback/FeedbackAdapter.ts +33 -0
  150. package/src/runtimes/adapters/speech/SpeechAdapterTypes.ts +47 -0
  151. package/src/runtimes/local/LocalRuntimeOptions.tsx +1 -1
  152. package/src/runtimes/local/index.ts +1 -1
  153. package/src/runtimes/remote-thread-list/adapter/cloud.tsx +1 -1
  154. package/dist/cloud/AssistantCloud.d.ts +0 -15
  155. package/dist/cloud/AssistantCloud.d.ts.map +0 -1
  156. package/dist/cloud/AssistantCloud.js +0 -25
  157. package/dist/cloud/AssistantCloud.js.map +0 -1
  158. package/dist/cloud/AssistantCloudAPI.d.ts +0 -28
  159. package/dist/cloud/AssistantCloudAPI.d.ts.map +0 -1
  160. package/dist/cloud/AssistantCloudAPI.js +0 -87
  161. package/dist/cloud/AssistantCloudAPI.js.map +0 -1
  162. package/dist/cloud/AssistantCloudAuthStrategy.d.ts +0 -30
  163. package/dist/cloud/AssistantCloudAuthStrategy.d.ts.map +0 -1
  164. package/dist/cloud/AssistantCloudAuthStrategy.js +0 -139
  165. package/dist/cloud/AssistantCloudAuthStrategy.js.map +0 -1
  166. package/dist/cloud/AssistantCloudAuthTokens.d.ts +0 -11
  167. package/dist/cloud/AssistantCloudAuthTokens.d.ts.map +0 -1
  168. package/dist/cloud/AssistantCloudAuthTokens.js +0 -13
  169. package/dist/cloud/AssistantCloudAuthTokens.js.map +0 -1
  170. package/dist/cloud/AssistantCloudFiles.d.ts +0 -27
  171. package/dist/cloud/AssistantCloudFiles.d.ts.map +0 -1
  172. package/dist/cloud/AssistantCloudFiles.js +0 -22
  173. package/dist/cloud/AssistantCloudFiles.js.map +0 -1
  174. package/dist/cloud/AssistantCloudRuns.d.ts +0 -26
  175. package/dist/cloud/AssistantCloudRuns.d.ts.map +0 -1
  176. package/dist/cloud/AssistantCloudRuns.js +0 -39
  177. package/dist/cloud/AssistantCloudRuns.js.map +0 -1
  178. package/dist/cloud/AssistantCloudThreadMessages.d.ts +0 -30
  179. package/dist/cloud/AssistantCloudThreadMessages.d.ts.map +0 -1
  180. package/dist/cloud/AssistantCloudThreadMessages.js +0 -21
  181. package/dist/cloud/AssistantCloudThreadMessages.js.map +0 -1
  182. package/dist/cloud/AssistantCloudThreads.d.ts +0 -48
  183. package/dist/cloud/AssistantCloudThreads.d.ts.map +0 -1
  184. package/dist/cloud/AssistantCloudThreads.js +0 -30
  185. package/dist/cloud/AssistantCloudThreads.js.map +0 -1
  186. package/src/cloud/AssistantCloud.tsx +0 -22
  187. package/src/cloud/AssistantCloudAPI.tsx +0 -121
  188. package/src/cloud/AssistantCloudAuthStrategy.tsx +0 -193
  189. package/src/cloud/AssistantCloudAuthTokens.tsx +0 -13
  190. package/src/cloud/AssistantCloudFiles.tsx +0 -45
  191. package/src/cloud/AssistantCloudRuns.tsx +0 -45
  192. package/src/cloud/AssistantCloudThreadMessages.tsx +0 -48
  193. package/src/cloud/AssistantCloudThreads.tsx +0 -79
  194. package/src/tests/AssistantCloudFiles.test.ts +0 -521
@@ -1,45 +0,0 @@
1
- import { ThreadMessage } from "../types";
2
- import { AssistantCloudAPI } from "./AssistantCloudAPI";
3
- import { AssistantStream, PlainTextDecoder } from "assistant-stream";
4
-
5
- type AssistantCloudRunsStreamBody = {
6
- thread_id: string;
7
- assistant_id: "system/thread_title";
8
- messages: readonly ThreadMessage[];
9
- };
10
-
11
- export class AssistantCloudRuns {
12
- constructor(private cloud: AssistantCloudAPI) {}
13
-
14
- public __internal_getAssistantOptions(assistantId: string) {
15
- return {
16
- api: this.cloud._baseUrl + "/v1/runs/stream",
17
- headers: async () => {
18
- const headers = await this.cloud._auth.getAuthHeaders();
19
- if (!headers) throw new Error("Authorization failed");
20
- return {
21
- ...headers,
22
- Accept: "text/plain",
23
- };
24
- },
25
- body: {
26
- assistant_id: assistantId,
27
- response_format: "vercel-ai-data-stream/v1",
28
- thread_id: "unstable_todo",
29
- },
30
- };
31
- }
32
-
33
- public async stream(
34
- body: AssistantCloudRunsStreamBody,
35
- ): Promise<AssistantStream> {
36
- const response = await this.cloud.makeRawRequest("/runs/stream", {
37
- method: "POST",
38
- headers: {
39
- Accept: "text/plain",
40
- },
41
- body,
42
- });
43
- return AssistantStream.fromResponse(response, new PlainTextDecoder());
44
- }
45
- }
@@ -1,48 +0,0 @@
1
- import { ReadonlyJSONObject } from "assistant-stream/utils";
2
- import { AssistantCloudAPI } from "./AssistantCloudAPI";
3
-
4
- export type CloudMessage = {
5
- id: string;
6
- parent_id: string | null;
7
- height: number;
8
- created_at: Date;
9
- updated_at: Date;
10
- format: "aui/v0" | string;
11
- content: ReadonlyJSONObject;
12
- };
13
-
14
- type AssistantCloudThreadMessageListResponse = {
15
- messages: CloudMessage[];
16
- };
17
-
18
- type AssistantCloudThreadMessageCreateBody = {
19
- parent_id: string | null;
20
- format: "aui/v0" | string;
21
- content: ReadonlyJSONObject;
22
- };
23
-
24
- type AssistantCloudMessageCreateResponse = {
25
- message_id: string;
26
- };
27
-
28
- export class AssistantCloudThreadMessages {
29
- constructor(private cloud: AssistantCloudAPI) {}
30
-
31
- public async list(
32
- threadId: string,
33
- ): Promise<AssistantCloudThreadMessageListResponse> {
34
- return this.cloud.makeRequest(
35
- `/threads/${encodeURIComponent(threadId)}/messages`,
36
- );
37
- }
38
-
39
- public async create(
40
- threadId: string,
41
- body: AssistantCloudThreadMessageCreateBody,
42
- ): Promise<AssistantCloudMessageCreateResponse> {
43
- return this.cloud.makeRequest(
44
- `/threads/${encodeURIComponent(threadId)}/messages`,
45
- { method: "POST", body },
46
- );
47
- }
48
- }
@@ -1,79 +0,0 @@
1
- import { AssistantCloudAPI } from "./AssistantCloudAPI";
2
- import { AssistantCloudThreadMessages } from "./AssistantCloudThreadMessages";
3
-
4
- type AssistantCloudThreadsListQuery = {
5
- is_archived?: boolean;
6
- limit?: number;
7
- after?: string;
8
- };
9
-
10
- type CloudThread = {
11
- title: string;
12
- last_message_at: Date;
13
- metadata: unknown;
14
- external_id: string | null;
15
- id: string;
16
- project_id: string;
17
- created_at: Date;
18
- updated_at: Date;
19
- workspace_id: string;
20
- is_archived: boolean;
21
- };
22
-
23
- type AssistantCloudThreadsListResponse = {
24
- threads: CloudThread[];
25
- };
26
-
27
- type AssistantCloudThreadsCreateBody = {
28
- title?: string | undefined;
29
- last_message_at: Date;
30
- metadata?: unknown | undefined;
31
- external_id?: string | undefined;
32
- };
33
-
34
- type AssistantCloudThreadsCreateResponse = {
35
- thread_id: string;
36
- };
37
-
38
- type AssistantCloudThreadsUpdateBody = {
39
- title?: string | undefined;
40
- last_message_at?: Date | undefined;
41
- metadata?: unknown | undefined;
42
- is_archived?: boolean | undefined;
43
- };
44
-
45
- export class AssistantCloudThreads {
46
- public readonly messages: AssistantCloudThreadMessages;
47
-
48
- constructor(private cloud: AssistantCloudAPI) {
49
- this.messages = new AssistantCloudThreadMessages(cloud);
50
- }
51
-
52
- public async list(
53
- query?: AssistantCloudThreadsListQuery,
54
- ): Promise<AssistantCloudThreadsListResponse> {
55
- return this.cloud.makeRequest("/threads", { query });
56
- }
57
-
58
- public async create(
59
- body: AssistantCloudThreadsCreateBody,
60
- ): Promise<AssistantCloudThreadsCreateResponse> {
61
- return this.cloud.makeRequest("/threads", { method: "POST", body });
62
- }
63
-
64
- public async update(
65
- threadId: string,
66
- body: AssistantCloudThreadsUpdateBody,
67
- ): Promise<void> {
68
- return this.cloud.makeRequest(`/threads/${encodeURIComponent(threadId)}`, {
69
- method: "PUT",
70
- body,
71
- });
72
- }
73
-
74
- public async delete(threadId: string): Promise<void> {
75
- return this.cloud.makeRequest(`/threads/${encodeURIComponent(threadId)}`, {
76
- method: "DELETE",
77
- });
78
- }
79
- }
@@ -1,521 +0,0 @@
1
- import { describe, it, expect, beforeEach, vi, afterEach } from "vitest";
2
- import { AssistantCloudFiles } from "../cloud/AssistantCloudFiles";
3
- import { AssistantCloudAPI } from "../cloud/AssistantCloudAPI";
4
-
5
- // Mock the AssistantCloudAPI to avoid making real HTTP requests (except for integration tests)
6
- vi.mock("../cloud/AssistantCloudAPI");
7
-
8
- describe("AssistantCloudFiles", () => {
9
- let cloudFiles: AssistantCloudFiles;
10
- let mockApi: AssistantCloudAPI;
11
-
12
- beforeEach(() => {
13
- // Create a mock API instance
14
- mockApi = {
15
- makeRequest: vi.fn(),
16
- makeRawRequest: vi.fn(),
17
- _auth: { getAuthHeaders: vi.fn() },
18
- _baseUrl: "https://backend.assistant-api.com",
19
- } as unknown as AssistantCloudAPI;
20
-
21
- // Create the AssistantCloudFiles instance with the mock API
22
- cloudFiles = new AssistantCloudFiles(mockApi);
23
- });
24
-
25
- afterEach(() => {
26
- vi.clearAllMocks();
27
- });
28
-
29
- describe("pdfToImages", () => {
30
- /**
31
- * Tests successful PDF to images conversion with file_url
32
- * This matches the curl request structure provided
33
- */
34
- it("should successfully convert PDF to images using file_url", async () => {
35
- const mockResponse = {
36
- success: true,
37
- urls: [
38
- "https://aui-pdf-processing.5c52327048f352f85fb041947c406ab4.r2.cloudflarestorage.com/images/8eb81c61-dc76-48fd-ab66-25cd84a28c97/page-1.png?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Content-Sha256=UNSIGNED-PAYLOAD&X-Amz-Credential=8698a7e98d990c6edd11fee3a9d0f3f0%2F20250606%2Fauto%2Fs3%2Faws4_request&X-Amz-Date=20250606T035428Z&X-Amz-Expires=3600&X-Amz-Signature=ea26cdd5ff7dc85eba12970137606484b9a8ab2c520f31ddba9cbe5941b20793&X-Amz-SignedHeaders=host&x-amz-checksum-mode=ENABLED&x-id=GetObject",
39
- "https://aui-pdf-processing.5c52327048f352f85fb041947c406ab4.r2.cloudflarestorage.com/images/8eb81c61-dc76-48fd-ab66-25cd84a28c97/page-2.png?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Content-Sha256=UNSIGNED-PAYLOAD&X-Amz-Credential=8698a7e98d990c6edd11fee3a9d0f3f0%2F20250606%2Fauto%2Fs3%2Faws4_request&X-Amz-Date=20250606T035428Z&X-Amz-Expires=3600&X-Amz-Signature=3499237770cc4402a60e6cc9b8ce8bd460faade9adf456d2773009f7d07af9cb&X-Amz-SignedHeaders=host&x-amz-checksum-mode=ENABLED&x-id=GetObject",
40
- "https://aui-pdf-processing.5c52327048f352f85fb041947c406ab4.r2.cloudflarestorage.com/images/8eb81c61-dc76-48fd-ab66-25cd84a28c97/page-3.png?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Content-Sha256=UNSIGNED-PAYLOAD&X-Amz-Credential=8698a7e98d990c6edd11fee3a9d0f3f0%2F20250606%2Fauto%2Fs3%2Faws4_request&X-Amz-Date=20250606T035429Z&X-Amz-Expires=3600&X-Amz-Signature=663ee073972f1b7b82cede9039ed4bc0a6c08118533a9586e871807baf032bc2&X-Amz-SignedHeaders=host&x-amz-checksum-mode=ENABLED&x-id=GetObject"
41
- ],
42
- message: "PDF successfully converted to images"
43
- };
44
-
45
- // Mock the API call to return our expected response
46
- vi.mocked(mockApi.makeRequest).mockResolvedValue(mockResponse);
47
-
48
- const requestBody = {
49
- file_url: "https://files.testfile.org/PDF/10MB-TESTFILE.ORG.pdf"
50
- };
51
-
52
- const result = await cloudFiles.pdfToImages(requestBody);
53
-
54
- // Verify the API was called correctly
55
- expect(mockApi.makeRequest).toHaveBeenCalledWith("/files/pdf-to-images", {
56
- method: "POST",
57
- body: requestBody,
58
- });
59
-
60
- // Verify the response structure
61
- expect(result).toEqual(mockResponse);
62
- expect(result.success).toBe(true);
63
- expect(result.urls).toHaveLength(3);
64
- expect(result.message).toBe("PDF successfully converted to images");
65
- expect(result.urls[0]).toContain("page-1.png");
66
- expect(result.urls[1]).toContain("page-2.png");
67
- expect(result.urls[2]).toContain("page-3.png");
68
- });
69
-
70
- /**
71
- * Tests successful PDF to images conversion with file_blob
72
- */
73
- it("should successfully convert PDF to images using file_blob", async () => {
74
- const mockResponse = {
75
- success: true,
76
- urls: [
77
- "https://example.com/converted-image-1.png",
78
- "https://example.com/converted-image-2.png"
79
- ],
80
- message: "PDF successfully converted to images"
81
- };
82
-
83
- vi.mocked(mockApi.makeRequest).mockResolvedValue(mockResponse);
84
-
85
- const requestBody = {
86
- file_blob: "data:application/pdf;base64,JVBERi0xLjQKJdPr6eEKMSAwIG9iago8PAovVHlwZSAvQ2F0YWxvZwovUGFnZXMgMiAwIFIKPj4KZW5kb2JqCjIgMCBvYmoKPDwKL1R5cGUgL1BhZ2VzCi9LaWRzIFszIDAgUl0KL0NvdW50IDEKL01lZGlhQm94IFswIDAgNTk1IDg0Ml0KPj4KZW5kb2JqCjMgMCBvYmoKPDwKL1R5cGUgL1BhZ2UKL1BhcmVudCAyIDAgUgovTWVkaWFCb3ggWzAgMCA1OTUgODQyXQovQ29udGVudHMgNCAwIFIKPj4KZW5kb2JqCjQgMCBvYmoKPDwKL0xlbmd0aCA0NAo+PgpzdHJlYW0KQlQKL0YxIDEyIFRmCjEwMCA3MDAgVGQKKFRlc3QgUERGKSBUagoKRVQKZW5kc3RyZWFtCmVuZG9iago1IDAgb2JqCjw8Ci9UeXBlIC9Gb250Ci9CYXNlRm9udCAvSGVsdmV0aWNhCi9TdWJ0eXBlIC9UeXBlMQo+PgplbmRvYmoKNiAwIG9iago8PAovVHlwZSAvRm9udERlc2NyaXB0b3IKL0ZvbnROYW1lIC9IZWx2ZXRpY2EKPj4KZW5kb2JqCnhyZWYKMCA3CjAwMDAwMDAwMDAgNjU1MzUgZiAKMDAwMDAwMDAwOSAwMDAwMCBuIAowMDAwMDAwMDc0IDAwMDAwIG4gCjAwMDAwMDAxMzMgMDAwMDAgbiAKMDAwMDAwMDIwNCAwMDAwMCBuIAowMDAwMDAwMjk5IDAwMDAwIG4gCjAwMDAwMDAzNzYgMDAwMDAgbiAKdHJhaWxlcgo8PAovU2l6ZSA3Ci9Sb290IDEgMCBSCj4+CnN0YXJ0eHJlZgo0MzQKJSVFT0YK"
87
- };
88
-
89
- const result = await cloudFiles.pdfToImages(requestBody);
90
-
91
- expect(mockApi.makeRequest).toHaveBeenCalledWith("/files/pdf-to-images", {
92
- method: "POST",
93
- body: requestBody,
94
- });
95
-
96
- expect(result).toEqual(mockResponse);
97
- expect(result.success).toBe(true);
98
- expect(result.urls).toHaveLength(2);
99
- });
100
-
101
- /**
102
- * Tests API error handling
103
- */
104
- it("should handle API errors gracefully", async () => {
105
- const errorMessage = "Invalid PDF file";
106
- vi.mocked(mockApi.makeRequest).mockRejectedValue(new Error(errorMessage));
107
-
108
- const requestBody = {
109
- file_url: "https://invalid-url.com/not-a-pdf.txt"
110
- };
111
-
112
- await expect(cloudFiles.pdfToImages(requestBody)).rejects.toThrow(errorMessage);
113
-
114
- expect(mockApi.makeRequest).toHaveBeenCalledWith("/files/pdf-to-images", {
115
- method: "POST",
116
- body: requestBody,
117
- });
118
- });
119
-
120
- /**
121
- * Tests handling of failed conversion response
122
- */
123
- it("should handle failed conversion response", async () => {
124
- const mockResponse = {
125
- success: false,
126
- urls: [],
127
- message: "Failed to convert PDF: File too large"
128
- };
129
-
130
- vi.mocked(mockApi.makeRequest).mockResolvedValue(mockResponse);
131
-
132
- const requestBody = {
133
- file_url: "https://example.com/huge-file.pdf"
134
- };
135
-
136
- const result = await cloudFiles.pdfToImages(requestBody);
137
-
138
- expect(result.success).toBe(false);
139
- expect(result.urls).toHaveLength(0);
140
- expect(result.message).toBe("Failed to convert PDF: File too large");
141
- });
142
-
143
- /**
144
- * Tests that the method works with both file_url and file_blob undefined (edge case)
145
- */
146
- it("should handle empty request body", async () => {
147
- const mockResponse = {
148
- success: false,
149
- urls: [],
150
- message: "No file provided"
151
- };
152
-
153
- vi.mocked(mockApi.makeRequest).mockResolvedValue(mockResponse);
154
-
155
- const requestBody = {};
156
-
157
- const result = await cloudFiles.pdfToImages(requestBody);
158
-
159
- expect(mockApi.makeRequest).toHaveBeenCalledWith("/files/pdf-to-images", {
160
- method: "POST",
161
- body: requestBody,
162
- });
163
-
164
- expect(result.success).toBe(false);
165
- expect(result.urls).toHaveLength(0);
166
- });
167
-
168
- /**
169
- * Tests that the method sends the correct request headers and structure
170
- * This ensures compatibility with the API key authentication shown in the curl example
171
- */
172
- it("should make request to correct endpoint with proper structure", async () => {
173
- const mockResponse = {
174
- success: true,
175
- urls: ["https://example.com/image.png"],
176
- message: "Success"
177
- };
178
-
179
- vi.mocked(mockApi.makeRequest).mockResolvedValue(mockResponse);
180
-
181
- const requestBody = {
182
- file_url: "https://files.testfile.org/PDF/10MB-TESTFILE.ORG.pdf"
183
- };
184
-
185
- await cloudFiles.pdfToImages(requestBody);
186
-
187
- // Verify the endpoint and method are correct
188
- expect(mockApi.makeRequest).toHaveBeenCalledWith("/files/pdf-to-images", {
189
- method: "POST",
190
- body: requestBody,
191
- });
192
-
193
- // Verify it was called exactly once
194
- expect(mockApi.makeRequest).toHaveBeenCalledTimes(1);
195
- });
196
-
197
- /**
198
- * Tests that both file_url and file_blob can be provided simultaneously
199
- */
200
- it("should handle request with both file_url and file_blob", async () => {
201
- const mockResponse = {
202
- success: true,
203
- urls: ["https://example.com/image.png"],
204
- message: "Success"
205
- };
206
-
207
- vi.mocked(mockApi.makeRequest).mockResolvedValue(mockResponse);
208
-
209
- const requestBody = {
210
- file_url: "https://example.com/file.pdf",
211
- file_blob: "base64data..."
212
- };
213
-
214
- const result = await cloudFiles.pdfToImages(requestBody);
215
-
216
- expect(mockApi.makeRequest).toHaveBeenCalledWith("/files/pdf-to-images", {
217
- method: "POST",
218
- body: requestBody,
219
- });
220
-
221
- expect(result).toEqual(mockResponse);
222
- });
223
- });
224
-
225
- describe("generatePresignedUploadUrl", () => {
226
- /**
227
- * Tests successful generation of presigned upload URL
228
- * This matches the curl request structure provided
229
- */
230
- it("should successfully generate presigned upload URL", async () => {
231
- const mockResponse = {
232
- success: true,
233
- signedUrl: "https://aui-cloud-attachments.5c52327048f352f85fb041947c406ab4.r2.cloudflarestorage.com/attachments/0204c5a7-cd09-470c-9488-96cf0be9db92.pdf?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Content-Sha256=UNSIGNED-PAYLOAD&X-Amz-Credential=8698a7e98d990c6edd11fee3a9d0f3f0%2F20250606%2Fauto%2Fs3%2Faws4_request&X-Amz-Date=20250606T051813Z&X-Amz-Expires=900&X-Amz-Signature=b0d27e7bee6200eb1964ad1d7f4a8ad76db15a3d99bd4fb47ff4b0b08fee5ca5&X-Amz-SignedHeaders=content-length%3Bhost&x-amz-checksum-crc32=AAAAAA%3D%3D&x-amz-meta-original-filename=hello.pdf&x-amz-meta-project-id=proj_09369w56dnge&x-amz-meta-user-id=676767&x-amz-sdk-checksum-algorithm=CRC32&x-id=PutObject",
234
- expiresAt: "2025-06-06T05:33:13.322Z",
235
- publicUrl: "https://storage.assistant-api.com/attachments/0204c5a7-cd09-470c-9488-96cf0be9db92.pdf"
236
- };
237
-
238
- // Mock the API call to return our expected response
239
- vi.mocked(mockApi.makeRequest).mockResolvedValue(mockResponse);
240
-
241
- const requestBody = {
242
- filename: "hello.pdf"
243
- };
244
-
245
- const result = await cloudFiles.generatePresignedUploadUrl(requestBody);
246
-
247
- // Verify the API was called correctly
248
- expect(mockApi.makeRequest).toHaveBeenCalledWith("/files/attachments/generate-presigned-upload-url", {
249
- method: "POST",
250
- body: requestBody,
251
- });
252
-
253
- // Verify the response structure
254
- expect(result).toEqual(mockResponse);
255
- expect(result.success).toBe(true);
256
- expect(result.signedUrl).toContain("aui-cloud-attachments");
257
- expect(result.signedUrl).toContain("X-Amz-Algorithm=AWS4-HMAC-SHA256");
258
- expect(result.expiresAt).toBe("2025-06-06T05:33:13.322Z");
259
- expect(result.publicUrl).toBe("https://storage.assistant-api.com/attachments/0204c5a7-cd09-470c-9488-96cf0be9db92.pdf");
260
- });
261
-
262
- /**
263
- * Tests generation with different file types
264
- */
265
- it("should successfully generate presigned upload URL for different file types", async () => {
266
- const mockResponse = {
267
- success: true,
268
- signedUrl: "https://aui-cloud-attachments.5c52327048f352f85fb041947c406ab4.r2.cloudflarestorage.com/attachments/test-image.png",
269
- expiresAt: "2025-06-06T05:33:13.322Z",
270
- publicUrl: "https://storage.assistant-api.com/attachments/test-image.png"
271
- };
272
-
273
- vi.mocked(mockApi.makeRequest).mockResolvedValue(mockResponse);
274
-
275
- const requestBody = {
276
- filename: "test-image.png"
277
- };
278
-
279
- const result = await cloudFiles.generatePresignedUploadUrl(requestBody);
280
-
281
- expect(mockApi.makeRequest).toHaveBeenCalledWith("/files/attachments/generate-presigned-upload-url", {
282
- method: "POST",
283
- body: requestBody,
284
- });
285
-
286
- expect(result).toEqual(mockResponse);
287
- expect(result.success).toBe(true);
288
- expect(result.publicUrl).toContain("test-image.png");
289
- });
290
-
291
- /**
292
- * Tests API error handling
293
- */
294
- it("should handle API errors gracefully", async () => {
295
- const errorMessage = "Invalid filename";
296
- vi.mocked(mockApi.makeRequest).mockRejectedValue(new Error(errorMessage));
297
-
298
- const requestBody = {
299
- filename: ""
300
- };
301
-
302
- await expect(cloudFiles.generatePresignedUploadUrl(requestBody)).rejects.toThrow(errorMessage);
303
-
304
- expect(mockApi.makeRequest).toHaveBeenCalledWith("/files/attachments/generate-presigned-upload-url", {
305
- method: "POST",
306
- body: requestBody,
307
- });
308
- });
309
-
310
- /**
311
- * Tests handling of failed response
312
- */
313
- it("should handle failed upload URL generation response", async () => {
314
- const mockResponse = {
315
- success: false,
316
- signedUrl: "",
317
- expiresAt: "",
318
- publicUrl: ""
319
- };
320
-
321
- vi.mocked(mockApi.makeRequest).mockResolvedValue(mockResponse);
322
-
323
- const requestBody = {
324
- filename: "invalid-file-type.exe"
325
- };
326
-
327
- const result = await cloudFiles.generatePresignedUploadUrl(requestBody);
328
-
329
- expect(result.success).toBe(false);
330
- expect(result.signedUrl).toBe("");
331
- expect(result.publicUrl).toBe("");
332
- });
333
-
334
- /**
335
- * Tests that the method sends the correct request headers and structure
336
- */
337
- it("should make request to correct endpoint with proper structure", async () => {
338
- const mockResponse = {
339
- success: true,
340
- signedUrl: "https://example.com/signed-url",
341
- expiresAt: "2025-06-06T05:33:13.322Z",
342
- publicUrl: "https://example.com/public-url"
343
- };
344
-
345
- vi.mocked(mockApi.makeRequest).mockResolvedValue(mockResponse);
346
-
347
- const requestBody = {
348
- filename: "document.pdf"
349
- };
350
-
351
- await cloudFiles.generatePresignedUploadUrl(requestBody);
352
-
353
- // Verify the endpoint and method are correct
354
- expect(mockApi.makeRequest).toHaveBeenCalledWith("/files/attachments/generate-presigned-upload-url", {
355
- method: "POST",
356
- body: requestBody,
357
- });
358
-
359
- // Verify it was called exactly once
360
- expect(mockApi.makeRequest).toHaveBeenCalledTimes(1);
361
- });
362
-
363
- /**
364
- * Tests filename validation scenarios
365
- */
366
- it("should handle various filename formats", async () => {
367
- const mockResponse = {
368
- success: true,
369
- signedUrl: "https://example.com/signed-url",
370
- expiresAt: "2025-06-06T05:33:13.322Z",
371
- publicUrl: "https://example.com/public-url"
372
- };
373
-
374
- vi.mocked(mockApi.makeRequest).mockResolvedValue(mockResponse);
375
-
376
- // Test with filename containing spaces and special characters
377
- const requestBody = {
378
- filename: "my document (final version).pdf"
379
- };
380
-
381
- const result = await cloudFiles.generatePresignedUploadUrl(requestBody);
382
-
383
- expect(mockApi.makeRequest).toHaveBeenCalledWith("/files/attachments/generate-presigned-upload-url", {
384
- method: "POST",
385
- body: requestBody,
386
- });
387
-
388
- expect(result).toEqual(mockResponse);
389
- });
390
- });
391
-
392
- // Integration test that actually calls the real API
393
- describe("Integration Tests", () => {
394
- /**
395
- * Integration test that actually calls the real API endpoint
396
- * This test requires real API credentials to be set in environment variables:
397
- * - AUI_API_KEY: Your API key (e.g., sk_aui_proj_...)
398
- * - AUI_USER_ID: Your user ID
399
- * - AUI_WORKSPACE_ID: Your workspace ID
400
- */
401
- it.skipIf(!process.env.AUI_API_KEY || !process.env.AUI_USER_ID || !process.env.AUI_WORKSPACE_ID)(
402
- "should actually convert PDF to images using real API", async () => {
403
- // Unmock all modules for this test to use real implementations
404
- vi.doUnmock("../cloud/AssistantCloudAPI");
405
- vi.doUnmock("../cloud/AssistantCloudFiles");
406
- vi.doUnmock("../cloud/AssistantCloud");
407
-
408
- // Clear all mocks and reload modules
409
- vi.resetModules();
410
-
411
- // Import real modules
412
- const { AssistantCloud: RealAssistantCloud } = await import("../cloud/AssistantCloud");
413
-
414
- const realCloud = new RealAssistantCloud({
415
- apiKey: process.env.AUI_API_KEY!,
416
- userId: process.env.AUI_USER_ID!,
417
- workspaceId: process.env.AUI_WORKSPACE_ID!,
418
- });
419
-
420
- const requestBody = {
421
- file_url: "https://files.testfile.org/PDF/10MB-TESTFILE.ORG.pdf"
422
- };
423
-
424
- console.log("Making API call to convert PDF...");
425
- const result = await realCloud.files.pdfToImages(requestBody);
426
- console.log("API call result:", result);
427
-
428
- // Verify the response structure
429
- expect(result).toHaveProperty("success");
430
- expect(result).toHaveProperty("urls");
431
- expect(result).toHaveProperty("message");
432
-
433
- if (result.success) {
434
- expect(Array.isArray(result.urls)).toBe(true);
435
- expect(result.urls.length).toBeGreaterThan(0);
436
- expect(typeof result.message).toBe("string");
437
-
438
- // Verify URLs are valid image URLs
439
- result.urls.forEach(url => {
440
- expect(url).toMatch(/^https:\/\/.+\.(png|jpg|jpeg)(\?.*)?$/i);
441
- });
442
- } else {
443
- // If it fails, at least verify the error message is a string
444
- expect(typeof result.message).toBe("string");
445
- console.log("API call failed:", result.message);
446
- }
447
-
448
- // Restore mocks after the test
449
- vi.doMock("../cloud/AssistantCloudAPI");
450
- },
451
- 60000 // 60 second timeout for real API calls
452
- );
453
-
454
- /**
455
- * Integration test for generatePresignedUploadUrl that actually calls the real API endpoint
456
- * This test requires real API credentials to be set in environment variables:
457
- * - AUI_API_KEY: Your API key (e.g., sk_aui_proj_...)
458
- * - AUI_USER_ID: Your user ID
459
- * - AUI_WORKSPACE_ID: Your workspace ID
460
- */
461
- it.skipIf(!process.env.AUI_API_KEY || !process.env.AUI_USER_ID || !process.env.AUI_WORKSPACE_ID)(
462
- "should actually generate presigned upload URL using real API", async () => {
463
- // Unmock all modules for this test to use real implementations
464
- vi.doUnmock("../cloud/AssistantCloudAPI");
465
- vi.doUnmock("../cloud/AssistantCloudFiles");
466
- vi.doUnmock("../cloud/AssistantCloud");
467
-
468
- // Clear all mocks and reload modules
469
- vi.resetModules();
470
-
471
- // Import real modules
472
- const { AssistantCloud: RealAssistantCloud } = await import("../cloud/AssistantCloud");
473
-
474
- const realCloud = new RealAssistantCloud({
475
- apiKey: process.env.AUI_API_KEY!,
476
- userId: process.env.AUI_USER_ID!,
477
- workspaceId: process.env.AUI_WORKSPACE_ID!,
478
- });
479
-
480
- const requestBody = {
481
- filename: "test-upload.pdf"
482
- };
483
-
484
- console.log("Making API call to generate presigned upload URL...");
485
- const result = await realCloud.files.generatePresignedUploadUrl(requestBody);
486
- console.log("API call result:", result);
487
-
488
- // Verify the response structure
489
- expect(result).toHaveProperty("success");
490
- expect(result).toHaveProperty("signedUrl");
491
- expect(result).toHaveProperty("expiresAt");
492
- expect(result).toHaveProperty("publicUrl");
493
-
494
- if (result.success) {
495
- expect(typeof result.signedUrl).toBe("string");
496
- expect(typeof result.expiresAt).toBe("string");
497
- expect(typeof result.publicUrl).toBe("string");
498
- expect(result.signedUrl.length).toBeGreaterThan(0);
499
- expect(result.publicUrl.length).toBeGreaterThan(0);
500
-
501
- // Verify URLs are valid HTTPS URLs
502
- expect(result.signedUrl).toMatch(/^https:\/\/.+/);
503
- expect(result.publicUrl).toMatch(/^https:\/\/.+/);
504
-
505
- // Verify the signed URL contains expected AWS signature parameters
506
- expect(result.signedUrl).toContain("X-Amz-Algorithm");
507
- expect(result.signedUrl).toContain("X-Amz-Signature");
508
-
509
- // Verify expiresAt is a valid ISO date string
510
- expect(() => new Date(result.expiresAt)).not.toThrow();
511
- } else {
512
- console.log("API call failed - this may be expected for some test cases");
513
- }
514
-
515
- // Restore mocks after the test
516
- vi.doMock("../cloud/AssistantCloudAPI");
517
- },
518
- 30000 // 30 second timeout for real API calls
519
- );
520
- });
521
- });