@assistant-ui/react 0.10.49 → 0.10.50

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.
@@ -1,9 +1,11 @@
1
1
  import { FC, ReactNode } from "react";
2
2
  import { ThreadHistoryAdapter } from "./thread-history/ThreadHistoryAdapter";
3
+ import { AttachmentAdapter } from "./attachment/AttachmentAdapter";
3
4
  import { ModelContextProvider } from "../../model-context";
4
5
  export type RuntimeAdapters = {
5
6
  modelContext?: ModelContextProvider;
6
7
  history?: ThreadHistoryAdapter;
8
+ attachments?: AttachmentAdapter;
7
9
  };
8
10
  declare namespace RuntimeAdapterProvider {
9
11
  type Props = {
@@ -1 +1 @@
1
- {"version":3,"file":"RuntimeAdapterProvider.d.ts","sourceRoot":"","sources":["../../../src/runtimes/adapters/RuntimeAdapterProvider.tsx"],"names":[],"mappings":"AAEA,OAAO,EAAiB,EAAE,EAAE,SAAS,EAAc,MAAM,OAAO,CAAC;AACjE,OAAO,EAAE,oBAAoB,EAAE,MAAM,uCAAuC,CAAC;AAC7E,OAAO,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAC;AAE3D,MAAM,MAAM,eAAe,GAAG;IAC5B,YAAY,CAAC,EAAE,oBAAoB,CAAC;IACpC,OAAO,CAAC,EAAE,oBAAoB,CAAC;CAChC,CAAC;AAIF,kBAAU,sBAAsB,CAAC;IAC/B,KAAY,KAAK,GAAG;QAClB,QAAQ,EAAE,eAAe,CAAC;QAC1B,QAAQ,EAAE,SAAS,CAAC;KACrB,CAAC;CACH;AAED,eAAO,MAAM,sBAAsB,EAAE,EAAE,CAAC,sBAAsB,CAAC,KAAK,CAenE,CAAC;AAEF,eAAO,MAAM,kBAAkB,8BAG9B,CAAC"}
1
+ {"version":3,"file":"RuntimeAdapterProvider.d.ts","sourceRoot":"","sources":["../../../src/runtimes/adapters/RuntimeAdapterProvider.tsx"],"names":[],"mappings":"AAEA,OAAO,EAAiB,EAAE,EAAE,SAAS,EAAc,MAAM,OAAO,CAAC;AACjE,OAAO,EAAE,oBAAoB,EAAE,MAAM,uCAAuC,CAAC;AAC7E,OAAO,EAAE,iBAAiB,EAAE,MAAM,gCAAgC,CAAC;AACnE,OAAO,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAC;AAE3D,MAAM,MAAM,eAAe,GAAG;IAC5B,YAAY,CAAC,EAAE,oBAAoB,CAAC;IACpC,OAAO,CAAC,EAAE,oBAAoB,CAAC;IAC/B,WAAW,CAAC,EAAE,iBAAiB,CAAC;CACjC,CAAC;AAIF,kBAAU,sBAAsB,CAAC;IAC/B,KAAY,KAAK,GAAG;QAClB,QAAQ,EAAE,eAAe,CAAC;QAC1B,QAAQ,EAAE,SAAS,CAAC;KACrB,CAAC;CACH;AAED,eAAO,MAAM,sBAAsB,EAAE,EAAE,CAAC,sBAAsB,CAAC,KAAK,CAenE,CAAC;AAEF,eAAO,MAAM,kBAAkB,8BAG9B,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/runtimes/adapters/RuntimeAdapterProvider.tsx"],"sourcesContent":["\"use client\";\n\nimport { createContext, FC, ReactNode, useContext } from \"react\";\nimport { ThreadHistoryAdapter } from \"./thread-history/ThreadHistoryAdapter\";\nimport { ModelContextProvider } from \"../../model-context\";\n\nexport type RuntimeAdapters = {\n modelContext?: ModelContextProvider;\n history?: ThreadHistoryAdapter;\n};\n\nconst RuntimeAdaptersContext = createContext<RuntimeAdapters | null>(null);\n\nnamespace RuntimeAdapterProvider {\n export type Props = {\n adapters: RuntimeAdapters;\n children: ReactNode;\n };\n}\n\nexport const RuntimeAdapterProvider: FC<RuntimeAdapterProvider.Props> = ({\n adapters,\n children,\n}) => {\n const context = useContext(RuntimeAdaptersContext);\n return (\n <RuntimeAdaptersContext.Provider\n value={{\n ...context,\n ...adapters,\n }}\n >\n {children}\n </RuntimeAdaptersContext.Provider>\n );\n};\n\nexport const useRuntimeAdapters = () => {\n const adapters = useContext(RuntimeAdaptersContext);\n return adapters;\n};\n"],"mappings":";;;AAEA,SAAS,eAA8B,kBAAkB;AAwBrD;AAfJ,IAAM,yBAAyB,cAAsC,IAAI;AASlE,IAAM,yBAA2D,CAAC;AAAA,EACvE;AAAA,EACA;AACF,MAAM;AACJ,QAAM,UAAU,WAAW,sBAAsB;AACjD,SACE;AAAA,IAAC,uBAAuB;AAAA,IAAvB;AAAA,MACC,OAAO;AAAA,QACL,GAAG;AAAA,QACH,GAAG;AAAA,MACL;AAAA,MAEC;AAAA;AAAA,EACH;AAEJ;AAEO,IAAM,qBAAqB,MAAM;AACtC,QAAM,WAAW,WAAW,sBAAsB;AAClD,SAAO;AACT;","names":[]}
1
+ {"version":3,"sources":["../../../src/runtimes/adapters/RuntimeAdapterProvider.tsx"],"sourcesContent":["\"use client\";\n\nimport { createContext, FC, ReactNode, useContext } from \"react\";\nimport { ThreadHistoryAdapter } from \"./thread-history/ThreadHistoryAdapter\";\nimport { AttachmentAdapter } from \"./attachment/AttachmentAdapter\";\nimport { ModelContextProvider } from \"../../model-context\";\n\nexport type RuntimeAdapters = {\n modelContext?: ModelContextProvider;\n history?: ThreadHistoryAdapter;\n attachments?: AttachmentAdapter;\n};\n\nconst RuntimeAdaptersContext = createContext<RuntimeAdapters | null>(null);\n\nnamespace RuntimeAdapterProvider {\n export type Props = {\n adapters: RuntimeAdapters;\n children: ReactNode;\n };\n}\n\nexport const RuntimeAdapterProvider: FC<RuntimeAdapterProvider.Props> = ({\n adapters,\n children,\n}) => {\n const context = useContext(RuntimeAdaptersContext);\n return (\n <RuntimeAdaptersContext.Provider\n value={{\n ...context,\n ...adapters,\n }}\n >\n {children}\n </RuntimeAdaptersContext.Provider>\n );\n};\n\nexport const useRuntimeAdapters = () => {\n const adapters = useContext(RuntimeAdaptersContext);\n return adapters;\n};\n"],"mappings":";;;AAEA,SAAS,eAA8B,kBAAkB;AA0BrD;AAfJ,IAAM,yBAAyB,cAAsC,IAAI;AASlE,IAAM,yBAA2D,CAAC;AAAA,EACvE;AAAA,EACA;AACF,MAAM;AACJ,QAAM,UAAU,WAAW,sBAAsB;AACjD,SACE;AAAA,IAAC,uBAAuB;AAAA,IAAvB;AAAA,MACC,OAAO;AAAA,QACL,GAAG;AAAA,QACH,GAAG;AAAA,MACL;AAAA,MAEC;AAAA;AAAA,EACH;AAEJ;AAEO,IAAM,qBAAqB,MAAM;AACtC,QAAM,WAAW,WAAW,sBAAsB;AAClD,SAAO;AACT;","names":[]}
@@ -0,0 +1,15 @@
1
+ import type { AssistantCloud } from "assistant-cloud";
2
+ import { Attachment, PendingAttachment, CompleteAttachment } from "../../../types/AttachmentTypes";
3
+ import { AttachmentAdapter } from "./AttachmentAdapter";
4
+ export declare class CloudFileAttachmentAdapter implements AttachmentAdapter {
5
+ private cloud;
6
+ accept: string;
7
+ constructor(cloud: AssistantCloud);
8
+ private uploadedUrls;
9
+ add({ file, }: {
10
+ file: File;
11
+ }): AsyncGenerator<PendingAttachment, void>;
12
+ remove(attachment: Attachment): Promise<void>;
13
+ send(attachment: PendingAttachment): Promise<CompleteAttachment>;
14
+ }
15
+ //# sourceMappingURL=CloudFileAttachmentAdapter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"CloudFileAttachmentAdapter.d.ts","sourceRoot":"","sources":["../../../../src/runtimes/adapters/attachment/CloudFileAttachmentAdapter.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AACtD,OAAO,EACL,UAAU,EACV,iBAAiB,EACjB,kBAAkB,EACnB,MAAM,gCAAgC,CAAC;AAExC,OAAO,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AAUxD,qBAAa,0BAA2B,YAAW,iBAAiB;IAGtD,OAAO,CAAC,KAAK;IAFlB,MAAM,SAAO;gBAEA,KAAK,EAAE,cAAc;IAEzC,OAAO,CAAC,YAAY,CAA6B;IAEnC,GAAG,CAAC,EAChB,IAAI,GACL,EAAE;QACD,IAAI,EAAE,IAAI,CAAC;KACZ,GAAG,cAAc,CAAC,iBAAiB,EAAE,IAAI,CAAC;IAyC9B,MAAM,CAAC,UAAU,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC;IAI7C,IAAI,CACf,UAAU,EAAE,iBAAiB,GAC5B,OAAO,CAAC,kBAAkB,CAAC;CAyB/B"}
@@ -0,0 +1,83 @@
1
+ // src/runtimes/adapters/attachment/CloudFileAttachmentAdapter.ts
2
+ var guessAttachmentType = (contentType) => {
3
+ if (contentType.startsWith("image/")) return "image";
4
+ if (contentType.startsWith("text/")) return "document";
5
+ return "file";
6
+ };
7
+ var CloudFileAttachmentAdapter = class {
8
+ constructor(cloud) {
9
+ this.cloud = cloud;
10
+ }
11
+ accept = "*";
12
+ uploadedUrls = /* @__PURE__ */ new Map();
13
+ async *add({
14
+ file
15
+ }) {
16
+ const id = crypto.randomUUID();
17
+ const type = guessAttachmentType(file.type);
18
+ let attachment = {
19
+ id,
20
+ type,
21
+ name: file.name,
22
+ contentType: file.type,
23
+ file,
24
+ status: { type: "running", reason: "uploading", progress: 0 }
25
+ };
26
+ yield attachment;
27
+ try {
28
+ const { signedUrl, publicUrl } = await this.cloud.files.generatePresignedUploadUrl({
29
+ filename: file.name
30
+ });
31
+ await fetch(signedUrl, {
32
+ method: "PUT",
33
+ body: file,
34
+ headers: {
35
+ "Content-Type": file.type
36
+ },
37
+ mode: "cors"
38
+ });
39
+ this.uploadedUrls.set(id, publicUrl);
40
+ attachment = {
41
+ ...attachment,
42
+ status: { type: "requires-action", reason: "composer-send" }
43
+ };
44
+ yield attachment;
45
+ } catch {
46
+ attachment = {
47
+ ...attachment,
48
+ status: { type: "incomplete", reason: "error" }
49
+ };
50
+ yield attachment;
51
+ }
52
+ }
53
+ async remove(attachment) {
54
+ this.uploadedUrls.delete(attachment.id);
55
+ }
56
+ async send(attachment) {
57
+ const url = this.uploadedUrls.get(attachment.id);
58
+ if (!url) throw new Error("Attachment not uploaded");
59
+ this.uploadedUrls.delete(attachment.id);
60
+ let content;
61
+ if (attachment.type === "image") {
62
+ content = [{ type: "image", image: url, filename: attachment.name }];
63
+ } else {
64
+ content = [
65
+ {
66
+ type: "file",
67
+ data: url,
68
+ mimeType: attachment.contentType,
69
+ filename: attachment.name
70
+ }
71
+ ];
72
+ }
73
+ return {
74
+ ...attachment,
75
+ status: { type: "complete" },
76
+ content
77
+ };
78
+ }
79
+ };
80
+ export {
81
+ CloudFileAttachmentAdapter
82
+ };
83
+ //# sourceMappingURL=CloudFileAttachmentAdapter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../../src/runtimes/adapters/attachment/CloudFileAttachmentAdapter.ts"],"sourcesContent":["import type { AssistantCloud } from \"assistant-cloud\";\nimport {\n Attachment,\n PendingAttachment,\n CompleteAttachment,\n} from \"../../../types/AttachmentTypes\";\nimport { ThreadUserMessagePart } from \"../../../types/MessagePartTypes\";\nimport { AttachmentAdapter } from \"./AttachmentAdapter\";\n\nconst guessAttachmentType = (\n contentType: string,\n): \"image\" | \"document\" | \"file\" => {\n if (contentType.startsWith(\"image/\")) return \"image\";\n if (contentType.startsWith(\"text/\")) return \"document\";\n return \"file\";\n};\n\nexport class CloudFileAttachmentAdapter implements AttachmentAdapter {\n public accept = \"*\";\n\n constructor(private cloud: AssistantCloud) {}\n\n private uploadedUrls = new Map<string, string>();\n\n public async *add({\n file,\n }: {\n file: File;\n }): AsyncGenerator<PendingAttachment, void> {\n const id = crypto.randomUUID();\n const type = guessAttachmentType(file.type);\n let attachment: PendingAttachment = {\n id,\n type,\n name: file.name,\n contentType: file.type,\n file,\n status: { type: \"running\", reason: \"uploading\", progress: 0 },\n };\n yield attachment;\n\n try {\n const { signedUrl, publicUrl } =\n await this.cloud.files.generatePresignedUploadUrl({\n filename: file.name,\n });\n await fetch(signedUrl, {\n method: \"PUT\",\n body: file,\n headers: {\n \"Content-Type\": file.type,\n },\n mode: \"cors\",\n });\n this.uploadedUrls.set(id, publicUrl);\n attachment = {\n ...attachment,\n status: { type: \"requires-action\", reason: \"composer-send\" },\n };\n yield attachment;\n } catch {\n attachment = {\n ...attachment,\n status: { type: \"incomplete\", reason: \"error\" },\n };\n yield attachment;\n }\n }\n\n public async remove(attachment: Attachment): Promise<void> {\n this.uploadedUrls.delete(attachment.id);\n }\n\n public async send(\n attachment: PendingAttachment,\n ): Promise<CompleteAttachment> {\n const url = this.uploadedUrls.get(attachment.id);\n if (!url) throw new Error(\"Attachment not uploaded\");\n this.uploadedUrls.delete(attachment.id);\n\n let content: ThreadUserMessagePart[];\n if (attachment.type === \"image\") {\n content = [{ type: \"image\", image: url, filename: attachment.name }];\n } else {\n content = [\n {\n type: \"file\",\n data: url,\n mimeType: attachment.contentType,\n filename: attachment.name,\n },\n ];\n }\n\n return {\n ...attachment,\n status: { type: \"complete\" },\n content,\n };\n }\n}\n"],"mappings":";AASA,IAAM,sBAAsB,CAC1B,gBACkC;AAClC,MAAI,YAAY,WAAW,QAAQ,EAAG,QAAO;AAC7C,MAAI,YAAY,WAAW,OAAO,EAAG,QAAO;AAC5C,SAAO;AACT;AAEO,IAAM,6BAAN,MAA8D;AAAA,EAGnE,YAAoB,OAAuB;AAAvB;AAAA,EAAwB;AAAA,EAFrC,SAAS;AAAA,EAIR,eAAe,oBAAI,IAAoB;AAAA,EAE/C,OAAc,IAAI;AAAA,IAChB;AAAA,EACF,GAE4C;AAC1C,UAAM,KAAK,OAAO,WAAW;AAC7B,UAAM,OAAO,oBAAoB,KAAK,IAAI;AAC1C,QAAI,aAAgC;AAAA,MAClC;AAAA,MACA;AAAA,MACA,MAAM,KAAK;AAAA,MACX,aAAa,KAAK;AAAA,MAClB;AAAA,MACA,QAAQ,EAAE,MAAM,WAAW,QAAQ,aAAa,UAAU,EAAE;AAAA,IAC9D;AACA,UAAM;AAEN,QAAI;AACF,YAAM,EAAE,WAAW,UAAU,IAC3B,MAAM,KAAK,MAAM,MAAM,2BAA2B;AAAA,QAChD,UAAU,KAAK;AAAA,MACjB,CAAC;AACH,YAAM,MAAM,WAAW;AAAA,QACrB,QAAQ;AAAA,QACR,MAAM;AAAA,QACN,SAAS;AAAA,UACP,gBAAgB,KAAK;AAAA,QACvB;AAAA,QACA,MAAM;AAAA,MACR,CAAC;AACD,WAAK,aAAa,IAAI,IAAI,SAAS;AACnC,mBAAa;AAAA,QACX,GAAG;AAAA,QACH,QAAQ,EAAE,MAAM,mBAAmB,QAAQ,gBAAgB;AAAA,MAC7D;AACA,YAAM;AAAA,IACR,QAAQ;AACN,mBAAa;AAAA,QACX,GAAG;AAAA,QACH,QAAQ,EAAE,MAAM,cAAc,QAAQ,QAAQ;AAAA,MAChD;AACA,YAAM;AAAA,IACR;AAAA,EACF;AAAA,EAEA,MAAa,OAAO,YAAuC;AACzD,SAAK,aAAa,OAAO,WAAW,EAAE;AAAA,EACxC;AAAA,EAEA,MAAa,KACX,YAC6B;AAC7B,UAAM,MAAM,KAAK,aAAa,IAAI,WAAW,EAAE;AAC/C,QAAI,CAAC,IAAK,OAAM,IAAI,MAAM,yBAAyB;AACnD,SAAK,aAAa,OAAO,WAAW,EAAE;AAEtC,QAAI;AACJ,QAAI,WAAW,SAAS,SAAS;AAC/B,gBAAU,CAAC,EAAE,MAAM,SAAS,OAAO,KAAK,UAAU,WAAW,KAAK,CAAC;AAAA,IACrE,OAAO;AACL,gBAAU;AAAA,QACR;AAAA,UACE,MAAM;AAAA,UACN,MAAM;AAAA,UACN,UAAU,WAAW;AAAA,UACrB,UAAU,WAAW;AAAA,QACvB;AAAA,MACF;AAAA,IACF;AAEA,WAAO;AAAA,MACL,GAAG;AAAA,MACH,QAAQ,EAAE,MAAM,WAAW;AAAA,MAC3B;AAAA,IACF;AAAA,EACF;AACF;","names":[]}
@@ -2,4 +2,5 @@ export type { AttachmentAdapter } from "./AttachmentAdapter";
2
2
  export { SimpleImageAttachmentAdapter } from "./SimpleImageAttachmentAdapter";
3
3
  export { SimpleTextAttachmentAdapter } from "./SimpleTextAttachmentAdapter";
4
4
  export { CompositeAttachmentAdapter } from "./CompositeAttachmentAdapter";
5
+ export { CloudFileAttachmentAdapter } from "./CloudFileAttachmentAdapter";
5
6
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/runtimes/adapters/attachment/index.ts"],"names":[],"mappings":"AAAA,YAAY,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AAC7D,OAAO,EAAE,4BAA4B,EAAE,MAAM,gCAAgC,CAAC;AAC9E,OAAO,EAAE,2BAA2B,EAAE,MAAM,+BAA+B,CAAC;AAC5E,OAAO,EAAE,0BAA0B,EAAE,MAAM,8BAA8B,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/runtimes/adapters/attachment/index.ts"],"names":[],"mappings":"AAAA,YAAY,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AAC7D,OAAO,EAAE,4BAA4B,EAAE,MAAM,gCAAgC,CAAC;AAC9E,OAAO,EAAE,2BAA2B,EAAE,MAAM,+BAA+B,CAAC;AAC5E,OAAO,EAAE,0BAA0B,EAAE,MAAM,8BAA8B,CAAC;AAC1E,OAAO,EAAE,0BAA0B,EAAE,MAAM,8BAA8B,CAAC"}
@@ -2,7 +2,9 @@
2
2
  import { SimpleImageAttachmentAdapter } from "./SimpleImageAttachmentAdapter.js";
3
3
  import { SimpleTextAttachmentAdapter } from "./SimpleTextAttachmentAdapter.js";
4
4
  import { CompositeAttachmentAdapter } from "./CompositeAttachmentAdapter.js";
5
+ import { CloudFileAttachmentAdapter } from "./CloudFileAttachmentAdapter.js";
5
6
  export {
7
+ CloudFileAttachmentAdapter,
6
8
  CompositeAttachmentAdapter,
7
9
  SimpleImageAttachmentAdapter,
8
10
  SimpleTextAttachmentAdapter
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../src/runtimes/adapters/attachment/index.ts"],"sourcesContent":["export type { AttachmentAdapter } from \"./AttachmentAdapter\";\nexport { SimpleImageAttachmentAdapter } from \"./SimpleImageAttachmentAdapter\";\nexport { SimpleTextAttachmentAdapter } from \"./SimpleTextAttachmentAdapter\";\nexport { CompositeAttachmentAdapter } from \"./CompositeAttachmentAdapter\";\n"],"mappings":";AACA,SAAS,oCAAoC;AAC7C,SAAS,mCAAmC;AAC5C,SAAS,kCAAkC;","names":[]}
1
+ {"version":3,"sources":["../../../../src/runtimes/adapters/attachment/index.ts"],"sourcesContent":["export type { AttachmentAdapter } from \"./AttachmentAdapter\";\nexport { SimpleImageAttachmentAdapter } from \"./SimpleImageAttachmentAdapter\";\nexport { SimpleTextAttachmentAdapter } from \"./SimpleTextAttachmentAdapter\";\nexport { CompositeAttachmentAdapter } from \"./CompositeAttachmentAdapter\";\nexport { CloudFileAttachmentAdapter } from \"./CloudFileAttachmentAdapter\";"],"mappings":";AACA,SAAS,oCAAoC;AAC7C,SAAS,mCAAmC;AAC5C,SAAS,kCAAkC;AAC3C,SAAS,kCAAkC;","names":[]}
@@ -1 +1 @@
1
- {"version":3,"file":"cloud.d.ts","sourceRoot":"","sources":["../../../../src/runtimes/remote-thread-list/adapter/cloud.tsx"],"names":[],"mappings":"AAUA,OAAO,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AACjD,OAAO,EAAE,uBAAuB,EAAE,MAAM,UAAU,CAAC;AAKnD,KAAK,UAAU,GAAG;IAChB,UAAU,EAAE,MAAM,CAAC;CACpB,CAAC;AAEF,KAAK,6BAA6B,GAAG;IACnC,KAAK,CAAC,EAAE,cAAc,GAAG,SAAS,CAAC;IAEnC,MAAM,CAAC,IAAI,OAAO,CAAC,UAAU,CAAC,CAAC;IAC/B,MAAM,CAAC,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CAC1C,CAAC;AASF,eAAO,MAAM,yBAAyB,GACpC,SAAS,6BAA6B,KACrC,uBA4EF,CAAC"}
1
+ {"version":3,"file":"cloud.d.ts","sourceRoot":"","sources":["../../../../src/runtimes/remote-thread-list/adapter/cloud.tsx"],"names":[],"mappings":"AAUA,OAAO,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AACjD,OAAO,EAAE,uBAAuB,EAAE,MAAM,UAAU,CAAC;AAMnD,KAAK,UAAU,GAAG;IAChB,UAAU,EAAE,MAAM,CAAC;CACpB,CAAC;AAEF,KAAK,6BAA6B,GAAG;IACnC,KAAK,CAAC,EAAE,cAAc,GAAG,SAAS,CAAC;IAEnC,MAAM,CAAC,IAAI,OAAO,CAAC,UAAU,CAAC,CAAC;IAC/B,MAAM,CAAC,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CAC1C,CAAC;AASF,eAAO,MAAM,yBAAyB,GACpC,SAAS,6BAA6B,KACrC,uBA0FF,CAAC"}
@@ -11,6 +11,7 @@ import { AssistantCloud } from "assistant-cloud";
11
11
  import { useAssistantCloudThreadHistoryAdapter } from "../../../cloud/AssistantCloudThreadHistoryAdapter.js";
12
12
  import { RuntimeAdapterProvider } from "../../adapters/RuntimeAdapterProvider.js";
13
13
  import { InMemoryThreadListAdapter } from "./in-memory.js";
14
+ import { CloudFileAttachmentAdapter } from "../../adapters/index.js";
14
15
  import { jsx } from "react/jsx-runtime";
15
16
  var baseUrl = typeof process !== "undefined" && process?.env?.["NEXT_PUBLIC_ASSISTANT_BASE_URL"];
16
17
  var autoCloud = baseUrl ? new AssistantCloud({ baseUrl, anonymous: true }) : void 0;
@@ -26,7 +27,19 @@ var useCloudThreadListAdapter = (adapter) => {
26
27
  return adapterRef.current.cloud ?? autoCloud;
27
28
  }
28
29
  });
29
- const adapters = useMemo(() => ({ history }), [history]);
30
+ const attachments = useMemo(
31
+ () => new CloudFileAttachmentAdapter(
32
+ adapterRef.current.cloud ?? autoCloud
33
+ ),
34
+ [adapterRef.current.cloud]
35
+ );
36
+ const adapters = useMemo(
37
+ () => ({
38
+ history,
39
+ attachments
40
+ }),
41
+ [history]
42
+ );
30
43
  return /* @__PURE__ */ jsx(RuntimeAdapterProvider, { adapters, children });
31
44
  },
32
45
  []
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../src/runtimes/remote-thread-list/adapter/cloud.tsx"],"sourcesContent":["\"use client\";\n\nimport {\n FC,\n PropsWithChildren,\n useCallback,\n useEffect,\n useMemo,\n useRef,\n} from \"react\";\nimport { AssistantCloud } from \"assistant-cloud\";\nimport { RemoteThreadListAdapter } from \"../types\";\nimport { useAssistantCloudThreadHistoryAdapter } from \"../../../cloud/AssistantCloudThreadHistoryAdapter\";\nimport { RuntimeAdapterProvider } from \"../../adapters/RuntimeAdapterProvider\";\nimport { InMemoryThreadListAdapter } from \"./in-memory\";\n\ntype ThreadData = {\n externalId: string;\n};\n\ntype CloudThreadListAdapterOptions = {\n cloud?: AssistantCloud | undefined;\n\n create?(): Promise<ThreadData>;\n delete?(threadId: string): Promise<void>;\n};\n\nconst baseUrl =\n typeof process !== \"undefined\" &&\n process?.env?.[\"NEXT_PUBLIC_ASSISTANT_BASE_URL\"];\nconst autoCloud = baseUrl\n ? new AssistantCloud({ baseUrl, anonymous: true })\n : undefined;\n\nexport const useCloudThreadListAdapter = (\n adapter: CloudThreadListAdapterOptions,\n): RemoteThreadListAdapter => {\n const adapterRef = useRef(adapter);\n useEffect(() => {\n adapterRef.current = adapter;\n }, [adapter]);\n\n const unstable_Provider = useCallback<FC<PropsWithChildren>>(\n function Provider({ children }) {\n const history = useAssistantCloudThreadHistoryAdapter({\n get current() {\n return adapterRef.current.cloud ?? autoCloud!;\n },\n });\n const adapters = useMemo(() => ({ history }), [history]);\n\n return (\n <RuntimeAdapterProvider adapters={adapters}>\n {children}\n </RuntimeAdapterProvider>\n );\n },\n [],\n );\n\n const cloud = adapter.cloud ?? autoCloud;\n if (!cloud) return new InMemoryThreadListAdapter();\n\n return {\n list: async () => {\n const { threads } = await cloud.threads.list();\n return {\n threads: threads.map((t) => ({\n status: t.is_archived ? \"archived\" : \"regular\",\n remoteId: t.id,\n title: t.title,\n externalId: t.external_id ?? undefined,\n })),\n };\n },\n\n initialize: async () => {\n const createTask = adapter.create?.() ?? Promise.resolve();\n const t = await createTask;\n const external_id = t ? t.externalId : undefined;\n const { thread_id: remoteId } = await cloud.threads.create({\n last_message_at: new Date(),\n external_id,\n });\n\n return { externalId: external_id, remoteId: remoteId };\n },\n\n rename: async (threadId, newTitle) => {\n return cloud.threads.update(threadId, { title: newTitle });\n },\n archive: async (threadId) => {\n return cloud.threads.update(threadId, { is_archived: true });\n },\n unarchive: async (threadId) => {\n return cloud.threads.update(threadId, { is_archived: false });\n },\n delete: async (threadId) => {\n await adapter.delete?.(threadId);\n return cloud.threads.delete(threadId);\n },\n\n generateTitle: async (threadId, messages) => {\n return cloud.runs.stream({\n thread_id: threadId,\n assistant_id: \"system/thread_title\",\n messages: messages, // TODO serialize these to a more efficient format\n });\n },\n\n unstable_Provider,\n };\n};\n"],"mappings":";;;AAEA;AAAA,EAGE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AACP,SAAS,sBAAsB;AAE/B,SAAS,6CAA6C;AACtD,SAAS,8BAA8B;AACvC,SAAS,iCAAiC;AAsClC;AAzBR,IAAM,UACJ,OAAO,YAAY,eACnB,SAAS,MAAM,gCAAgC;AACjD,IAAM,YAAY,UACd,IAAI,eAAe,EAAE,SAAS,WAAW,KAAK,CAAC,IAC/C;AAEG,IAAM,4BAA4B,CACvC,YAC4B;AAC5B,QAAM,aAAa,OAAO,OAAO;AACjC,YAAU,MAAM;AACd,eAAW,UAAU;AAAA,EACvB,GAAG,CAAC,OAAO,CAAC;AAEZ,QAAM,oBAAoB;AAAA,IACxB,SAAS,SAAS,EAAE,SAAS,GAAG;AAC9B,YAAM,UAAU,sCAAsC;AAAA,QACpD,IAAI,UAAU;AACZ,iBAAO,WAAW,QAAQ,SAAS;AAAA,QACrC;AAAA,MACF,CAAC;AACD,YAAM,WAAW,QAAQ,OAAO,EAAE,QAAQ,IAAI,CAAC,OAAO,CAAC;AAEvD,aACE,oBAAC,0BAAuB,UACrB,UACH;AAAA,IAEJ;AAAA,IACA,CAAC;AAAA,EACH;AAEA,QAAM,QAAQ,QAAQ,SAAS;AAC/B,MAAI,CAAC,MAAO,QAAO,IAAI,0BAA0B;AAEjD,SAAO;AAAA,IACL,MAAM,YAAY;AAChB,YAAM,EAAE,QAAQ,IAAI,MAAM,MAAM,QAAQ,KAAK;AAC7C,aAAO;AAAA,QACL,SAAS,QAAQ,IAAI,CAAC,OAAO;AAAA,UAC3B,QAAQ,EAAE,cAAc,aAAa;AAAA,UACrC,UAAU,EAAE;AAAA,UACZ,OAAO,EAAE;AAAA,UACT,YAAY,EAAE,eAAe;AAAA,QAC/B,EAAE;AAAA,MACJ;AAAA,IACF;AAAA,IAEA,YAAY,YAAY;AACtB,YAAM,aAAa,QAAQ,SAAS,KAAK,QAAQ,QAAQ;AACzD,YAAM,IAAI,MAAM;AAChB,YAAM,cAAc,IAAI,EAAE,aAAa;AACvC,YAAM,EAAE,WAAW,SAAS,IAAI,MAAM,MAAM,QAAQ,OAAO;AAAA,QACzD,iBAAiB,oBAAI,KAAK;AAAA,QAC1B;AAAA,MACF,CAAC;AAED,aAAO,EAAE,YAAY,aAAa,SAAmB;AAAA,IACvD;AAAA,IAEA,QAAQ,OAAO,UAAU,aAAa;AACpC,aAAO,MAAM,QAAQ,OAAO,UAAU,EAAE,OAAO,SAAS,CAAC;AAAA,IAC3D;AAAA,IACA,SAAS,OAAO,aAAa;AAC3B,aAAO,MAAM,QAAQ,OAAO,UAAU,EAAE,aAAa,KAAK,CAAC;AAAA,IAC7D;AAAA,IACA,WAAW,OAAO,aAAa;AAC7B,aAAO,MAAM,QAAQ,OAAO,UAAU,EAAE,aAAa,MAAM,CAAC;AAAA,IAC9D;AAAA,IACA,QAAQ,OAAO,aAAa;AAC1B,YAAM,QAAQ,SAAS,QAAQ;AAC/B,aAAO,MAAM,QAAQ,OAAO,QAAQ;AAAA,IACtC;AAAA,IAEA,eAAe,OAAO,UAAU,aAAa;AAC3C,aAAO,MAAM,KAAK,OAAO;AAAA,QACvB,WAAW;AAAA,QACX,cAAc;AAAA,QACd;AAAA;AAAA,MACF,CAAC;AAAA,IACH;AAAA,IAEA;AAAA,EACF;AACF;","names":[]}
1
+ {"version":3,"sources":["../../../../src/runtimes/remote-thread-list/adapter/cloud.tsx"],"sourcesContent":["\"use client\";\n\nimport {\n FC,\n PropsWithChildren,\n useCallback,\n useEffect,\n useMemo,\n useRef,\n} from \"react\";\nimport { AssistantCloud } from \"assistant-cloud\";\nimport { RemoteThreadListAdapter } from \"../types\";\nimport { useAssistantCloudThreadHistoryAdapter } from \"../../../cloud/AssistantCloudThreadHistoryAdapter\";\nimport { RuntimeAdapterProvider } from \"../../adapters/RuntimeAdapterProvider\";\nimport { InMemoryThreadListAdapter } from \"./in-memory\";\nimport { CloudFileAttachmentAdapter } from \"../../adapters\";\n\ntype ThreadData = {\n externalId: string;\n};\n\ntype CloudThreadListAdapterOptions = {\n cloud?: AssistantCloud | undefined;\n\n create?(): Promise<ThreadData>;\n delete?(threadId: string): Promise<void>;\n};\n\nconst baseUrl =\n typeof process !== \"undefined\" &&\n process?.env?.[\"NEXT_PUBLIC_ASSISTANT_BASE_URL\"];\nconst autoCloud = baseUrl\n ? new AssistantCloud({ baseUrl, anonymous: true })\n : undefined;\n\nexport const useCloudThreadListAdapter = (\n adapter: CloudThreadListAdapterOptions,\n): RemoteThreadListAdapter => {\n const adapterRef = useRef(adapter);\n useEffect(() => {\n adapterRef.current = adapter;\n }, [adapter]);\n\n const unstable_Provider = useCallback<FC<PropsWithChildren>>(\n function Provider({ children }) {\n const history = useAssistantCloudThreadHistoryAdapter({\n get current() {\n return adapterRef.current.cloud ?? autoCloud!;\n },\n });\n const attachments = useMemo(\n () =>\n new CloudFileAttachmentAdapter(\n adapterRef.current.cloud ?? autoCloud!,\n ),\n [adapterRef.current.cloud],\n );\n\n const adapters = useMemo(\n () => ({\n history,\n attachments,\n }),\n [history],\n );\n\n return (\n <RuntimeAdapterProvider adapters={adapters}>\n {children}\n </RuntimeAdapterProvider>\n );\n },\n [],\n );\n\n const cloud = adapter.cloud ?? autoCloud;\n if (!cloud) return new InMemoryThreadListAdapter();\n\n return {\n list: async () => {\n const { threads } = await cloud.threads.list();\n return {\n threads: threads.map((t) => ({\n status: t.is_archived ? \"archived\" : \"regular\",\n remoteId: t.id,\n title: t.title,\n externalId: t.external_id ?? undefined,\n })),\n };\n },\n\n initialize: async () => {\n const createTask = adapter.create?.() ?? Promise.resolve();\n const t = await createTask;\n const external_id = t ? t.externalId : undefined;\n const { thread_id: remoteId } = await cloud.threads.create({\n last_message_at: new Date(),\n external_id,\n });\n\n return { externalId: external_id, remoteId: remoteId };\n },\n\n rename: async (threadId, newTitle) => {\n return cloud.threads.update(threadId, { title: newTitle });\n },\n archive: async (threadId) => {\n return cloud.threads.update(threadId, { is_archived: true });\n },\n unarchive: async (threadId) => {\n return cloud.threads.update(threadId, { is_archived: false });\n },\n delete: async (threadId) => {\n await adapter.delete?.(threadId);\n return cloud.threads.delete(threadId);\n },\n\n generateTitle: async (threadId, messages) => {\n return cloud.runs.stream({\n thread_id: threadId,\n assistant_id: \"system/thread_title\",\n messages: messages, // TODO serialize these to a more efficient format\n });\n },\n\n unstable_Provider,\n };\n};\n"],"mappings":";;;AAEA;AAAA,EAGE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AACP,SAAS,sBAAsB;AAE/B,SAAS,6CAA6C;AACtD,SAAS,8BAA8B;AACvC,SAAS,iCAAiC;AAC1C,SAAS,kCAAkC;AAoDnC;AAvCR,IAAM,UACJ,OAAO,YAAY,eACnB,SAAS,MAAM,gCAAgC;AACjD,IAAM,YAAY,UACd,IAAI,eAAe,EAAE,SAAS,WAAW,KAAK,CAAC,IAC/C;AAEG,IAAM,4BAA4B,CACvC,YAC4B;AAC5B,QAAM,aAAa,OAAO,OAAO;AACjC,YAAU,MAAM;AACd,eAAW,UAAU;AAAA,EACvB,GAAG,CAAC,OAAO,CAAC;AAEZ,QAAM,oBAAoB;AAAA,IACxB,SAAS,SAAS,EAAE,SAAS,GAAG;AAC9B,YAAM,UAAU,sCAAsC;AAAA,QACpD,IAAI,UAAU;AACZ,iBAAO,WAAW,QAAQ,SAAS;AAAA,QACrC;AAAA,MACF,CAAC;AACD,YAAM,cAAc;AAAA,QAClB,MACE,IAAI;AAAA,UACF,WAAW,QAAQ,SAAS;AAAA,QAC9B;AAAA,QACF,CAAC,WAAW,QAAQ,KAAK;AAAA,MAC3B;AAEA,YAAM,WAAW;AAAA,QACf,OAAO;AAAA,UACL;AAAA,UACA;AAAA,QACF;AAAA,QACA,CAAC,OAAO;AAAA,MACV;AAEA,aACE,oBAAC,0BAAuB,UACrB,UACH;AAAA,IAEJ;AAAA,IACA,CAAC;AAAA,EACH;AAEA,QAAM,QAAQ,QAAQ,SAAS;AAC/B,MAAI,CAAC,MAAO,QAAO,IAAI,0BAA0B;AAEjD,SAAO;AAAA,IACL,MAAM,YAAY;AAChB,YAAM,EAAE,QAAQ,IAAI,MAAM,MAAM,QAAQ,KAAK;AAC7C,aAAO;AAAA,QACL,SAAS,QAAQ,IAAI,CAAC,OAAO;AAAA,UAC3B,QAAQ,EAAE,cAAc,aAAa;AAAA,UACrC,UAAU,EAAE;AAAA,UACZ,OAAO,EAAE;AAAA,UACT,YAAY,EAAE,eAAe;AAAA,QAC/B,EAAE;AAAA,MACJ;AAAA,IACF;AAAA,IAEA,YAAY,YAAY;AACtB,YAAM,aAAa,QAAQ,SAAS,KAAK,QAAQ,QAAQ;AACzD,YAAM,IAAI,MAAM;AAChB,YAAM,cAAc,IAAI,EAAE,aAAa;AACvC,YAAM,EAAE,WAAW,SAAS,IAAI,MAAM,MAAM,QAAQ,OAAO;AAAA,QACzD,iBAAiB,oBAAI,KAAK;AAAA,QAC1B;AAAA,MACF,CAAC;AAED,aAAO,EAAE,YAAY,aAAa,SAAmB;AAAA,IACvD;AAAA,IAEA,QAAQ,OAAO,UAAU,aAAa;AACpC,aAAO,MAAM,QAAQ,OAAO,UAAU,EAAE,OAAO,SAAS,CAAC;AAAA,IAC3D;AAAA,IACA,SAAS,OAAO,aAAa;AAC3B,aAAO,MAAM,QAAQ,OAAO,UAAU,EAAE,aAAa,KAAK,CAAC;AAAA,IAC7D;AAAA,IACA,WAAW,OAAO,aAAa;AAC7B,aAAO,MAAM,QAAQ,OAAO,UAAU,EAAE,aAAa,MAAM,CAAC;AAAA,IAC9D;AAAA,IACA,QAAQ,OAAO,aAAa;AAC1B,YAAM,QAAQ,SAAS,QAAQ;AAC/B,aAAO,MAAM,QAAQ,OAAO,QAAQ;AAAA,IACtC;AAAA,IAEA,eAAe,OAAO,UAAU,aAAa;AAC3C,aAAO,MAAM,KAAK,OAAO;AAAA,QACvB,WAAW;AAAA,QACX,cAAc;AAAA,QACd;AAAA;AAAA,MACF,CAAC;AAAA,IACH;AAAA,IAEA;AAAA,EACF;AACF;","names":[]}
package/package.json CHANGED
@@ -28,7 +28,7 @@
28
28
  "conversational-ui",
29
29
  "conversational-ai"
30
30
  ],
31
- "version": "0.10.49",
31
+ "version": "0.10.50",
32
32
  "license": "MIT",
33
33
  "type": "module",
34
34
  "exports": {
@@ -2,11 +2,13 @@
2
2
 
3
3
  import { createContext, FC, ReactNode, useContext } from "react";
4
4
  import { ThreadHistoryAdapter } from "./thread-history/ThreadHistoryAdapter";
5
+ import { AttachmentAdapter } from "./attachment/AttachmentAdapter";
5
6
  import { ModelContextProvider } from "../../model-context";
6
7
 
7
8
  export type RuntimeAdapters = {
8
9
  modelContext?: ModelContextProvider;
9
10
  history?: ThreadHistoryAdapter;
11
+ attachments?: AttachmentAdapter;
10
12
  };
11
13
 
12
14
  const RuntimeAdaptersContext = createContext<RuntimeAdapters | null>(null);
@@ -0,0 +1,101 @@
1
+ import type { AssistantCloud } from "assistant-cloud";
2
+ import {
3
+ Attachment,
4
+ PendingAttachment,
5
+ CompleteAttachment,
6
+ } from "../../../types/AttachmentTypes";
7
+ import { ThreadUserMessagePart } from "../../../types/MessagePartTypes";
8
+ import { AttachmentAdapter } from "./AttachmentAdapter";
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
+ }
@@ -2,3 +2,4 @@ export type { AttachmentAdapter } from "./AttachmentAdapter";
2
2
  export { SimpleImageAttachmentAdapter } from "./SimpleImageAttachmentAdapter";
3
3
  export { SimpleTextAttachmentAdapter } from "./SimpleTextAttachmentAdapter";
4
4
  export { CompositeAttachmentAdapter } from "./CompositeAttachmentAdapter";
5
+ export { CloudFileAttachmentAdapter } from "./CloudFileAttachmentAdapter";
@@ -13,6 +13,7 @@ import { RemoteThreadListAdapter } from "../types";
13
13
  import { useAssistantCloudThreadHistoryAdapter } from "../../../cloud/AssistantCloudThreadHistoryAdapter";
14
14
  import { RuntimeAdapterProvider } from "../../adapters/RuntimeAdapterProvider";
15
15
  import { InMemoryThreadListAdapter } from "./in-memory";
16
+ import { CloudFileAttachmentAdapter } from "../../adapters";
16
17
 
17
18
  type ThreadData = {
18
19
  externalId: string;
@@ -47,7 +48,21 @@ export const useCloudThreadListAdapter = (
47
48
  return adapterRef.current.cloud ?? autoCloud!;
48
49
  },
49
50
  });
50
- const adapters = useMemo(() => ({ history }), [history]);
51
+ const attachments = useMemo(
52
+ () =>
53
+ new CloudFileAttachmentAdapter(
54
+ adapterRef.current.cloud ?? autoCloud!,
55
+ ),
56
+ [adapterRef.current.cloud],
57
+ );
58
+
59
+ const adapters = useMemo(
60
+ () => ({
61
+ history,
62
+ attachments,
63
+ }),
64
+ [history],
65
+ );
51
66
 
52
67
  return (
53
68
  <RuntimeAdapterProvider adapters={adapters}>