@assistant-ui/react 0.15.4 → 0.15.7

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 (64) hide show
  1. package/dist/client/ExternalThread.d.ts.map +1 -1
  2. package/dist/client/ExternalThread.js +384 -368
  3. package/dist/client/ExternalThread.js.map +1 -1
  4. package/dist/context/providers/MessageProvider.js +15 -34
  5. package/dist/context/providers/MessageProvider.js.map +1 -1
  6. package/dist/index.d.ts +3 -3
  7. package/dist/index.js +2 -2
  8. package/dist/legacy-runtime/AssistantRuntimeProvider.d.ts +6 -1
  9. package/dist/legacy-runtime/AssistantRuntimeProvider.d.ts.map +1 -1
  10. package/dist/legacy-runtime/AssistantRuntimeProvider.js +10 -8
  11. package/dist/legacy-runtime/AssistantRuntimeProvider.js.map +1 -1
  12. package/dist/legacy-runtime/runtime-cores/assistant-transport/runManager.d.ts.map +1 -1
  13. package/dist/legacy-runtime/runtime-cores/assistant-transport/runManager.js +8 -1
  14. package/dist/legacy-runtime/runtime-cores/assistant-transport/runManager.js.map +1 -1
  15. package/dist/legacy-runtime/runtime-cores/assistant-transport/types.d.ts +5 -1
  16. package/dist/legacy-runtime/runtime-cores/assistant-transport/types.d.ts.map +1 -1
  17. package/dist/legacy-runtime/runtime-cores/assistant-transport/useAssistantTransportRuntime.d.ts.map +1 -1
  18. package/dist/legacy-runtime/runtime-cores/assistant-transport/useAssistantTransportRuntime.js +44 -3
  19. package/dist/legacy-runtime/runtime-cores/assistant-transport/useAssistantTransportRuntime.js.map +1 -1
  20. package/dist/primitives/actionBar/ActionBarExportMarkdown.js +1 -1
  21. package/dist/primitives/actionBar/ActionBarExportMarkdown.js.map +1 -1
  22. package/dist/primitives/attachment/AttachmentThumb.d.ts.map +1 -1
  23. package/dist/primitives/attachment/AttachmentThumb.js +17 -14
  24. package/dist/primitives/attachment/AttachmentThumb.js.map +1 -1
  25. package/dist/primitives/composer/ComposerAttachmentDropzone.d.ts.map +1 -1
  26. package/dist/primitives/composer/ComposerAttachmentDropzone.js +64 -50
  27. package/dist/primitives/composer/ComposerAttachmentDropzone.js.map +1 -1
  28. package/dist/primitives/composer/ComposerInput.js +1 -0
  29. package/dist/primitives/composer/ComposerInput.js.map +1 -1
  30. package/dist/primitives/queueItem/QueueItemText.d.ts.map +1 -1
  31. package/dist/primitives/queueItem/QueueItemText.js +10 -4
  32. package/dist/primitives/queueItem/QueueItemText.js.map +1 -1
  33. package/dist/primitives/selectionToolbar/SelectionToolbarRoot.d.ts.map +1 -1
  34. package/dist/primitives/selectionToolbar/SelectionToolbarRoot.js +5 -4
  35. package/dist/primitives/selectionToolbar/SelectionToolbarRoot.js.map +1 -1
  36. package/dist/utils/createActionButton.js +1 -1
  37. package/dist/utils/createActionButton.js.map +1 -1
  38. package/dist/utils/useToolArgsFieldStatus.d.ts +2 -2
  39. package/package.json +16 -14
  40. package/src/client/ExternalThread.ts +30 -17
  41. package/src/context/providers/MessageProvider.tsx +8 -6
  42. package/src/index.ts +5 -1
  43. package/src/legacy-runtime/AssistantRuntimeProvider.tsx +13 -3
  44. package/src/legacy-runtime/runtime-cores/assistant-transport/runManager.ts +14 -1
  45. package/src/legacy-runtime/runtime-cores/assistant-transport/transport-scheduling.test.ts +38 -0
  46. package/src/legacy-runtime/runtime-cores/assistant-transport/types.ts +5 -1
  47. package/src/legacy-runtime/runtime-cores/assistant-transport/useAssistantTransport.spec.md +7 -0
  48. package/src/legacy-runtime/runtime-cores/assistant-transport/useAssistantTransportRuntime.test.tsx +290 -0
  49. package/src/legacy-runtime/runtime-cores/assistant-transport/useAssistantTransportRuntime.ts +62 -1
  50. package/src/primitives/actionBar/ActionBarExportMarkdown.tsx +1 -1
  51. package/src/primitives/attachment/AttachmentThumb.test.tsx +70 -0
  52. package/src/primitives/attachment/AttachmentThumb.tsx +8 -4
  53. package/src/primitives/composer/ComposerAttachmentDropzone.test.tsx +103 -3
  54. package/src/primitives/composer/ComposerAttachmentDropzone.tsx +18 -3
  55. package/src/primitives/composer/ComposerInput.test.tsx +53 -2
  56. package/src/primitives/composer/ComposerInput.tsx +3 -0
  57. package/src/primitives/queueItem/QueueItemText.tsx +8 -2
  58. package/src/primitives/selectionToolbar/SelectionToolbarRoot.test.tsx +74 -0
  59. package/src/primitives/selectionToolbar/SelectionToolbarRoot.tsx +3 -3
  60. package/src/tests/external-thread-parity.test.tsx +52 -4
  61. package/src/tests/local-runtime-queue.test.tsx +199 -6
  62. package/src/utils/createActionButton.test.tsx +18 -0
  63. package/src/utils/createActionButton.tsx +1 -1
  64. package/LICENSE +0 -21
@@ -2,6 +2,9 @@ import { useLatestRef } from "./useLatestRef.js";
2
2
  import { useCallback, useEffect, useRef, useState } from "@assistant-ui/tap/react-shim";
3
3
  //#region src/legacy-runtime/runtime-cores/assistant-transport/runManager.ts
4
4
  const disposeReason = Symbol("assistant-transport-dispose");
5
+ const reportFinishError = (error) => {
6
+ console.error("[assistant-ui] Assistant transport onFinish callback threw an error", error);
7
+ };
5
8
  function useRunManager(config) {
6
9
  const [isRunning, setIsRunning] = useState(false);
7
10
  const stateRef = useRef({
@@ -29,7 +32,11 @@ function useRunManager(config) {
29
32
  else await onErrorRef.current?.(error);
30
33
  }
31
34
  } finally {
32
- if (!disposeAborted() && !stateRef.current.disposed) onFinishRef.current?.();
35
+ if (!disposeAborted() && !stateRef.current.disposed) try {
36
+ Promise.resolve(onFinishRef.current?.()).catch(reportFinishError);
37
+ } catch (error) {
38
+ reportFinishError(error);
39
+ }
33
40
  if (!stateRef.current.disposed && stateRef.current.pending) startRun();
34
41
  else {
35
42
  setIsRunning(false);
@@ -1 +1 @@
1
- {"version":3,"file":"runManager.js","names":["useCallback","useEffect","useRef","useState","useLatestRef","RunManager","Readonly","isRunning","schedule","cancel","disposeReason","Symbol","useRunManager","config","onRun","signal","AbortSignal","Promise","onFinish","onCancel","onError","error","Error","setIsRunning","stateRef","pending","disposed","abortController","AbortController","onRunRef","onFinishRef","onCancelRef","onErrorRef","startRun","current","ac","disposeAborted","reason","queueMicrotask","aborted","abort"],"sources":["../../../../src/legacy-runtime/runtime-cores/assistant-transport/runManager.ts"],"sourcesContent":["import { useCallback, useEffect, useRef, useState } from \"react\";\nimport { useLatestRef } from \"./useLatestRef\";\n\nexport type RunManager = Readonly<{\n isRunning: boolean;\n schedule: () => void;\n cancel: () => void;\n}>;\n\nconst disposeReason = Symbol(\"assistant-transport-dispose\");\n\nexport function useRunManager(config: {\n onRun: (signal: AbortSignal) => Promise<void>;\n onFinish?: (() => void) | undefined;\n onCancel?: (() => void) | undefined;\n onError?: ((error: Error) => void | Promise<void>) | undefined;\n}): RunManager {\n const [isRunning, setIsRunning] = useState(false);\n const stateRef = useRef({\n pending: false,\n disposed: false,\n abortController: null as AbortController | null,\n });\n const onRunRef = useLatestRef(config.onRun);\n const onFinishRef = useLatestRef(config.onFinish);\n const onCancelRef = useLatestRef(config.onCancel);\n const onErrorRef = useLatestRef(config.onError);\n\n const startRun = useCallback(() => {\n setIsRunning(true);\n stateRef.current.pending = false;\n const ac = new AbortController();\n stateRef.current.abortController = ac;\n\n // The dispose marker rides on the abort reason so a settling run detects\n // its own disposal even after an effect cycle re-arms the manager.\n const disposeAborted = () => ac.signal.reason === disposeReason;\n\n queueMicrotask(async () => {\n try {\n if (!disposeAborted()) {\n await onRunRef.current(ac.signal);\n }\n } catch (error) {\n if (!disposeAborted() && !stateRef.current.disposed) {\n stateRef.current.pending = false;\n if (ac.signal.aborted) {\n onCancelRef.current?.();\n } else {\n await onErrorRef.current?.(error as Error);\n }\n }\n } finally {\n if (!disposeAborted() && !stateRef.current.disposed) {\n onFinishRef.current?.();\n }\n if (!stateRef.current.disposed && stateRef.current.pending) {\n startRun();\n } else {\n setIsRunning(false);\n if (stateRef.current.abortController === ac) {\n stateRef.current.abortController = null;\n }\n }\n }\n });\n }, [onRunRef, onFinishRef, onErrorRef, onCancelRef]);\n\n const schedule = useCallback(() => {\n if (stateRef.current.disposed) return;\n if (stateRef.current.abortController) {\n // Coalesce multiple schedules while running into a single follow-up run.\n stateRef.current.pending = true;\n return;\n }\n startRun();\n }, [startRun]);\n\n // Strict-mode effects run setup / cleanup / setup on the same instance;\n // arming on setup undoes the cleanup's dispose.\n useEffect(() => {\n stateRef.current.disposed = false;\n return () => {\n stateRef.current.disposed = true;\n stateRef.current.pending = false;\n stateRef.current.abortController?.abort(disposeReason);\n };\n }, []);\n\n const cancel = useCallback(() => {\n stateRef.current.pending = false;\n stateRef.current.abortController?.abort();\n }, []);\n\n return {\n isRunning,\n schedule,\n cancel,\n };\n}\n"],"mappings":";;;AASA,MAAMU,gBAAgBC,OAAO,6BAA6B;AAE1D,SAAgBC,cAAcC,QAKf;CACb,MAAM,CAACN,WAAWgB,gBAAgBpB,SAAS,KAAK;CAChD,MAAMqB,WAAWtB,OAAO;EACtBuB,SAAS;EACTC,UAAU;EACVC,iBAAiB;CACnB,CAAC;CACD,MAAME,WAAWzB,aAAaS,OAAOC,KAAK;CAC1C,MAAMgB,cAAc1B,aAAaS,OAAOK,QAAQ;CAChD,MAAMa,cAAc3B,aAAaS,OAAOM,QAAQ;CAChD,MAAMa,aAAa5B,aAAaS,OAAOO,OAAO;CAE9C,MAAMa,WAAWjC,kBAAkB;EACjCuB,aAAa,IAAI;EACjBC,SAASU,QAAQT,UAAU;EAC3B,MAAMU,KAAK,IAAIP,gBAAgB;EAC/BJ,SAASU,QAAQP,kBAAkBQ;EAInC,MAAMC,uBAAuBD,GAAGpB,OAAOsB,WAAW3B;EAElD4B,eAAe,YAAY;GACzB,IAAI;IACF,IAAI,CAACF,eAAe,GAClB,MAAMP,SAASK,QAAQC,GAAGpB,MAAM;GAEpC,SAASM,OAAO;IACd,IAAI,CAACe,eAAe,KAAK,CAACZ,SAASU,QAAQR,UAAU;KACnDF,SAASU,QAAQT,UAAU;KAC3B,IAAIU,GAAGpB,OAAOwB,SACZR,YAAYG,UAAU;UAEtB,MAAMF,WAAWE,UAAUb,KAAc;IAE7C;GACF,UAAU;IACR,IAAI,CAACe,eAAe,KAAK,CAACZ,SAASU,QAAQR,UACzCI,YAAYI,UAAU;IAExB,IAAI,CAACV,SAASU,QAAQR,YAAYF,SAASU,QAAQT,SACjDQ,SAAS;SACJ;KACLV,aAAa,KAAK;KAClB,IAAIC,SAASU,QAAQP,oBAAoBQ,IACvCX,SAASU,QAAQP,kBAAkB;IAEvC;GACF;EACF,CAAC;CACH,GAAG;EAACE;EAAUC;EAAaE;EAAYD;CAAW,CAAC;CAEnD,MAAMvB,WAAWR,kBAAkB;EACjC,IAAIwB,SAASU,QAAQR,UAAU;EAC/B,IAAIF,SAASU,QAAQP,iBAAiB;GAEpCH,SAASU,QAAQT,UAAU;GAC3B;EACF;EACAQ,SAAS;CACX,GAAG,CAACA,QAAQ,CAAC;CAIbhC,gBAAgB;EACduB,SAASU,QAAQR,WAAW;EAC5B,aAAa;GACXF,SAASU,QAAQR,WAAW;GAC5BF,SAASU,QAAQT,UAAU;GAC3BD,SAASU,QAAQP,iBAAiBa,MAAM9B,aAAa;EACvD;CACF,GAAG,CAAA,CAAE;CAOL,OAAO;EACLH;EACAC;EACAC,QARaT,kBAAkB;GAC/BwB,SAASU,QAAQT,UAAU;GAC3BD,SAASU,QAAQP,iBAAiBa,MAAM;EAC1C,GAAG,CAAA,CAKD/B;CACF;AACF"}
1
+ {"version":3,"file":"runManager.js","names":["useCallback","useEffect","useRef","useState","useLatestRef","RunManager","Readonly","isRunning","schedule","cancel","disposeReason","Symbol","reportFinishError","error","console","useRunManager","config","onRun","signal","AbortSignal","Promise","onFinish","onCancel","onError","Error","setIsRunning","stateRef","pending","disposed","abortController","AbortController","onRunRef","onFinishRef","onCancelRef","onErrorRef","startRun","current","ac","disposeAborted","reason","queueMicrotask","aborted","resolve","catch","abort"],"sources":["../../../../src/legacy-runtime/runtime-cores/assistant-transport/runManager.ts"],"sourcesContent":["import { useCallback, useEffect, useRef, useState } from \"react\";\nimport { useLatestRef } from \"./useLatestRef\";\n\nexport type RunManager = Readonly<{\n isRunning: boolean;\n schedule: () => void;\n cancel: () => void;\n}>;\n\nconst disposeReason = Symbol(\"assistant-transport-dispose\");\n\nconst reportFinishError = (error: unknown) => {\n console.error(\n \"[assistant-ui] Assistant transport onFinish callback threw an error\",\n error,\n );\n};\n\nexport function useRunManager(config: {\n onRun: (signal: AbortSignal) => Promise<void>;\n onFinish?: (() => void) | undefined;\n onCancel?: (() => void) | undefined;\n onError?: ((error: Error) => void | Promise<void>) | undefined;\n}): RunManager {\n const [isRunning, setIsRunning] = useState(false);\n const stateRef = useRef({\n pending: false,\n disposed: false,\n abortController: null as AbortController | null,\n });\n const onRunRef = useLatestRef(config.onRun);\n const onFinishRef = useLatestRef(config.onFinish);\n const onCancelRef = useLatestRef(config.onCancel);\n const onErrorRef = useLatestRef(config.onError);\n\n const startRun = useCallback(() => {\n setIsRunning(true);\n stateRef.current.pending = false;\n const ac = new AbortController();\n stateRef.current.abortController = ac;\n\n // The dispose marker rides on the abort reason so a settling run detects\n // its own disposal even after an effect cycle re-arms the manager.\n const disposeAborted = () => ac.signal.reason === disposeReason;\n\n queueMicrotask(async () => {\n try {\n if (!disposeAborted()) {\n await onRunRef.current(ac.signal);\n }\n } catch (error) {\n if (!disposeAborted() && !stateRef.current.disposed) {\n stateRef.current.pending = false;\n if (ac.signal.aborted) {\n onCancelRef.current?.();\n } else {\n await onErrorRef.current?.(error as Error);\n }\n }\n } finally {\n if (!disposeAborted() && !stateRef.current.disposed) {\n try {\n void Promise.resolve(onFinishRef.current?.()).catch(\n reportFinishError,\n );\n } catch (error) {\n reportFinishError(error);\n }\n }\n if (!stateRef.current.disposed && stateRef.current.pending) {\n startRun();\n } else {\n setIsRunning(false);\n if (stateRef.current.abortController === ac) {\n stateRef.current.abortController = null;\n }\n }\n }\n });\n }, [onRunRef, onFinishRef, onErrorRef, onCancelRef]);\n\n const schedule = useCallback(() => {\n if (stateRef.current.disposed) return;\n if (stateRef.current.abortController) {\n // Coalesce multiple schedules while running into a single follow-up run.\n stateRef.current.pending = true;\n return;\n }\n startRun();\n }, [startRun]);\n\n // Strict-mode effects run setup / cleanup / setup on the same instance;\n // arming on setup undoes the cleanup's dispose.\n useEffect(() => {\n stateRef.current.disposed = false;\n return () => {\n stateRef.current.disposed = true;\n stateRef.current.pending = false;\n stateRef.current.abortController?.abort(disposeReason);\n };\n }, []);\n\n const cancel = useCallback(() => {\n stateRef.current.pending = false;\n stateRef.current.abortController?.abort();\n }, []);\n\n return {\n isRunning,\n schedule,\n cancel,\n };\n}\n"],"mappings":";;;AASA,MAAMU,gBAAgBC,OAAO,6BAA6B;AAE1D,MAAMC,qBAAqBC,UAAmB;CAC5CC,QAAQD,MACN,uEACAA,KACF;AACF;AAEA,SAAgBE,cAAcC,QAKf;CACb,MAAM,CAACT,WAAWkB,gBAAgBtB,SAAS,KAAK;CAChD,MAAMuB,WAAWxB,OAAO;EACtByB,SAAS;EACTC,UAAU;EACVC,iBAAiB;CACnB,CAAC;CACD,MAAME,WAAW3B,aAAaY,OAAOC,KAAK;CAC1C,MAAMe,cAAc5B,aAAaY,OAAOK,QAAQ;CAChD,MAAMY,cAAc7B,aAAaY,OAAOM,QAAQ;CAChD,MAAMY,aAAa9B,aAAaY,OAAOO,OAAO;CAE9C,MAAMY,WAAWnC,kBAAkB;EACjCyB,aAAa,IAAI;EACjBC,SAASU,QAAQT,UAAU;EAC3B,MAAMU,KAAK,IAAIP,gBAAgB;EAC/BJ,SAASU,QAAQP,kBAAkBQ;EAInC,MAAMC,uBAAuBD,GAAGnB,OAAOqB,WAAW7B;EAElD8B,eAAe,YAAY;GACzB,IAAI;IACF,IAAI,CAACF,eAAe,GAClB,MAAMP,SAASK,QAAQC,GAAGnB,MAAM;GAEpC,SAASL,OAAO;IACd,IAAI,CAACyB,eAAe,KAAK,CAACZ,SAASU,QAAQR,UAAU;KACnDF,SAASU,QAAQT,UAAU;KAC3B,IAAIU,GAAGnB,OAAOuB,SACZR,YAAYG,UAAU;UAEtB,MAAMF,WAAWE,UAAUvB,KAAc;IAE7C;GACF,UAAU;IACR,IAAI,CAACyB,eAAe,KAAK,CAACZ,SAASU,QAAQR,UACzC,IAAI;KACF,QAAac,QAAQV,YAAYI,UAAU,CAAC,CAAC,CAACO,MAC5C/B,iBACF;IACF,SAASC,OAAO;KACdD,kBAAkBC,KAAK;IACzB;IAEF,IAAI,CAACa,SAASU,QAAQR,YAAYF,SAASU,QAAQT,SACjDQ,SAAS;SACJ;KACLV,aAAa,KAAK;KAClB,IAAIC,SAASU,QAAQP,oBAAoBQ,IACvCX,SAASU,QAAQP,kBAAkB;IAEvC;GACF;EACF,CAAC;CACH,GAAG;EAACE;EAAUC;EAAaE;EAAYD;CAAW,CAAC;CAEnD,MAAMzB,WAAWR,kBAAkB;EACjC,IAAI0B,SAASU,QAAQR,UAAU;EAC/B,IAAIF,SAASU,QAAQP,iBAAiB;GAEpCH,SAASU,QAAQT,UAAU;GAC3B;EACF;EACAQ,SAAS;CACX,GAAG,CAACA,QAAQ,CAAC;CAIblC,gBAAgB;EACdyB,SAASU,QAAQR,WAAW;EAC5B,aAAa;GACXF,SAASU,QAAQR,WAAW;GAC5BF,SAASU,QAAQT,UAAU;GAC3BD,SAASU,QAAQP,iBAAiBe,MAAMlC,aAAa;EACvD;CACF,GAAG,CAAA,CAAE;CAOL,OAAO;EACLH;EACAC;EACAC,QARaT,kBAAkB;GAC/B0B,SAASU,QAAQT,UAAU;GAC3BD,SAASU,QAAQP,iBAAiBe,MAAM;EAC1C,GAAG,CAAA,CAKDnC;CACF;AACF"}
@@ -56,7 +56,9 @@ type HeadersValue = Record<string, string> | Headers;
56
56
  type AssistantTransportProtocol = "data-stream" | "assistant-transport";
57
57
  type SendCommandsRequestBody = {
58
58
  commands: QueuedCommand[];
59
- state: unknown;
59
+ /** Absent on a resume with `resumeStateApi`; the server replays from its retained snapshot. */
60
+ state?: unknown;
61
+ runId?: string;
60
62
  system: string | undefined;
61
63
  tools: Record<string, unknown> | undefined;
62
64
  callSettings: LanguageModelV1CallSettings | undefined;
@@ -69,6 +71,8 @@ type AssistantTransportOptions<T> = {
69
71
  initialState: T;
70
72
  api: string;
71
73
  resumeApi?: string;
74
+ /** Endpoint that returns the retained initial state and run ID for a resume stream. A 204 response means no run is active and the resume is skipped. */
75
+ resumeStateApi?: string;
72
76
  protocol?: AssistantTransportProtocol;
73
77
  /**
74
78
  * When `false`, stream decoding and state reconciliation tolerate malformed
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","names":[],"sources":["../../../../src/legacy-runtime/runtime-cores/assistant-transport/types.ts"],"mappings":";;;;;KAaY;WACD;WACA;;KAGC;WACD;WACA;;KAGC,kBAAkB,WAAW;KAE7B;WACD;WACA,gBAAgB;;KAGf;WACD;WACA,gBAAgB;;KAIf;WACD;WACA,SAAS,cAAc;WACvB;WACA;;KAGC;WACD;WACA;WACA;WACA,QAAQ;WACR;WACA,WAAW;WACX,wBAAwB;;KAGvB,4BACR,oBACA,uBACA;KAGQ;WACD,mBAAmB;WACnB,QAAQ;WACR;;KAGC;EACV,iBAAiB;EACjB;EACA,cAAc,eAAe;;KAGnB,iCAAiC,MAC3C,OAAO,GACP,oBAAoB,yCACjB;KAGO;EACV,QAAQ;EACR,WAAW;;KAID,gBAAgB;KAKhB,eAAe,yBAAyB;KAExC;KAEA;EACV,UAAU;EACV;EACA;EACA,OAAO;EACP,cAAc;EACd,QAAQ;EACR;EACA;GAIC;;KAGS,0BAA0B;EACpC,cAAc;EACd;EACA;EACA,WAAW;;;;;;EAMX;EACA,WAAW,iCAAiC;EAC5C,SAAS,sBAAsB,QAAQ;EACvC,uBAAuB;;;;;;;;;;;;;EAavB,8BACE,MAAM,4BACH,0BAA0B,QAAQ;EACvC,cAAc,UAAU;EACxB;EACA,WACE,OAAO,OACP;IACE,UAAU;IACV,cAAc,UAAU,OAAO,MAAM;eAE7B;;;;;;;EAOZ,YAAY;IACV,UAAU;IACV,cAAc,UAAU,OAAO,MAAM;IACrC,QAAQ;;EAEV;IACE;;EAEF;IACE,cAAc;IACd,UAAU"}
1
+ {"version":3,"file":"types.d.ts","names":[],"sources":["../../../../src/legacy-runtime/runtime-cores/assistant-transport/types.ts"],"mappings":";;;;;KAaY;WACD;WACA;;KAGC;WACD;WACA;;KAGC,kBAAkB,WAAW;KAE7B;WACD;WACA,gBAAgB;;KAGf;WACD;WACA,gBAAgB;;KAIf;WACD;WACA,SAAS,cAAc;WACvB;WACA;;KAGC;WACD;WACA;WACA;WACA,QAAQ;WACR;WACA,WAAW;WACX,wBAAwB;;KAGvB,4BACR,oBACA,uBACA;KAGQ;WACD,mBAAmB;WACnB,QAAQ;WACR;;KAGC;EACV,iBAAiB;EACjB;EACA,cAAc,eAAe;;KAGnB,iCAAiC,MAC3C,OAAO,GACP,oBAAoB,yCACjB;KAGO;EACV,QAAQ;EACR,WAAW;;KAID,gBAAgB;KAKhB,eAAe,yBAAyB;KAExC;KAEA;EACV,UAAU;;EAEV;EACA;EACA;EACA,OAAO;EACP,cAAc;EACd,QAAQ;EACR;EACA;GAIC;;KAGS,0BAA0B;EACpC,cAAc;EACd;EACA;;EAEA;EACA,WAAW;;;;;;EAMX;EACA,WAAW,iCAAiC;EAC5C,SAAS,sBAAsB,QAAQ;EACvC,uBAAuB;;;;;;;;;;;;;EAavB,8BACE,MAAM,4BACH,0BAA0B,QAAQ;EACvC,cAAc,UAAU;EACxB;EACA,WACE,OAAO,OACP;IACE,UAAU;IACV,cAAc,UAAU,OAAO,MAAM;eAE7B;;;;;;;EAOZ,YAAY;IACV,UAAU;IACV,cAAc,UAAU,OAAO,MAAM;IACrC,QAAQ;;EAEV;IACE;;EAEF;IACE,cAAc;IACd,UAAU"}
@@ -1 +1 @@
1
- {"version":3,"file":"useAssistantTransportRuntime.d.ts","names":[],"sources":["../../../../src/legacy-runtime/runtime-cores/assistant-transport/useAssistantTransportRuntime.ts"],"mappings":";;;;cAgGa,yCAGH,SAAS;iBAOH,8BAA8B;iBAC9B,2BAA2B,GACzC,WAAW,OAAO,sBAAsB,IACvC;;;;cAoSU,+BAAgC,GAC3C,SAAS,0BAA0B,OAClC"}
1
+ {"version":3,"file":"useAssistantTransportRuntime.d.ts","names":[],"sources":["../../../../src/legacy-runtime/runtime-cores/assistant-transport/useAssistantTransportRuntime.ts"],"mappings":";;;;cA8Ha,yCAGH,SAAS;iBAOH,8BAA8B;iBAC9B,2BAA2B,GACzC,WAAW,OAAO,sBAAsB,IACvC;;;;cAmUU,+BAAgC,GAC3C,SAAS,0BAA0B,OAClC"}
@@ -35,6 +35,21 @@ const convertAppendMessageToCommand = (message) => {
35
35
  sourceId: message.sourceId
36
36
  };
37
37
  };
38
+ const readResumeState = async (response) => {
39
+ if (response.status === 204) return null;
40
+ if (!response.ok) throw new Error(`Resume state request failed with status ${response.status}: ${await response.text()}`);
41
+ let value;
42
+ try {
43
+ value = await response.json();
44
+ } catch {
45
+ throw new Error("Resume state response was not valid JSON");
46
+ }
47
+ if (typeof value !== "object" || value === null || !("state" in value) || !("runId" in value) || typeof value.runId !== "string") throw new Error("Resume state response must contain state and runId");
48
+ return {
49
+ runId: value.runId,
50
+ state: value.state
51
+ };
52
+ };
38
53
  const symbolAssistantTransportExtras = Symbol("assistant-transport-extras");
39
54
  const asAssistantTransportExtras = (extras) => {
40
55
  if (typeof extras !== "object" || extras == null || !(symbolAssistantTransportExtras in extras)) throw new Error("This method can only be called when you are using useAssistantTransportRuntime");
@@ -85,11 +100,26 @@ const useAssistantTransportThreadRuntime = (options) => {
85
100
  const parentId = isResume ? void 0 : parentIdRef.current;
86
101
  if (!isResume) parentIdRef.current = void 0;
87
102
  const headers = await createRequestHeaders(options.headers);
103
+ let resumeState;
104
+ if (isResume && options.resumeStateApi) {
105
+ const resumeStateResponse = await fetch(options.resumeStateApi, {
106
+ method: "POST",
107
+ headers,
108
+ body: JSON.stringify({ threadId }),
109
+ signal
110
+ });
111
+ const retained = await readResumeState(resumeStateResponse);
112
+ if (retained === null) {
113
+ if (commandQueue.state.queued.length > 0) runManager.schedule();
114
+ return;
115
+ }
116
+ resumeState = retained;
117
+ }
88
118
  const bodyValue = typeof options.body === "function" ? await options.body() : options.body;
89
119
  const context = runtime.thread.getModelContext();
90
120
  let requestBody = {
91
121
  commands,
92
- state: agentStateRef.current,
122
+ ...resumeState === void 0 && { state: agentStateRef.current },
93
123
  system: context.system,
94
124
  tools: context.tools ? toToolsJSONSchema(context.tools) : void 0,
95
125
  threadId,
@@ -101,6 +131,13 @@ const useAssistantTransportThreadRuntime = (options) => {
101
131
  ...bodyValue ?? {}
102
132
  };
103
133
  if (options.prepareSendCommandsRequest) requestBody = await options.prepareSendCommandsRequest(requestBody);
134
+ if (resumeState !== void 0) {
135
+ requestBody = {
136
+ ...requestBody,
137
+ runId: resumeState.runId
138
+ };
139
+ delete requestBody["state"];
140
+ }
104
141
  const response = await fetch(isResume ? options.resumeApi : options.api, {
105
142
  method: "POST",
106
143
  headers,
@@ -110,6 +147,10 @@ const useAssistantTransportThreadRuntime = (options) => {
110
147
  options.onResponse?.(response);
111
148
  if (!response.ok) throw new Error(`Status ${response.status}: ${await response.text()}`);
112
149
  if (!response.body) throw new Error("Response body is null");
150
+ if (resumeState !== void 0) {
151
+ agentStateRef.current = resumeState.state;
152
+ rerender((prev) => prev + 1);
153
+ }
113
154
  const body = await createReplayBoundaryStream(response, {
114
155
  setReplaying: setIsReplaying,
115
156
  waitForRender: waitForReplayRender
@@ -149,7 +190,7 @@ const useAssistantTransportThreadRuntime = (options) => {
149
190
  commands: cmds,
150
191
  updateState: (updater) => {
151
192
  agentStateRef.current = updater(agentStateRef.current);
152
- rerender((prev) => prev + 1);
193
+ rerender((prev_0) => prev_0 + 1);
153
194
  }
154
195
  });
155
196
  },
@@ -224,7 +265,7 @@ const useAssistantTransportThreadRuntime = (options) => {
224
265
  },
225
266
  onLoadExternalState: async (state) => {
226
267
  agentStateRef.current = state;
227
- rerender((prev_0) => prev_0 + 1);
268
+ rerender((prev_1) => prev_1 + 1);
228
269
  }
229
270
  });
230
271
  return runtime;
@@ -1 +1 @@
1
- {"version":3,"file":"useAssistantTransportRuntime.js","names":["c","_c","AppendMessage","ReadonlyJSONObject","ReadonlyJSONValue","asAsyncIterableStream","useExternalStoreRuntime","AssistantRuntime","AddToolResultOptions","useMemo","useRef","useState","AssistantMessageAccumulator","DataStreamDecoder","AssistantTransportDecoder","unstable_createInitialMessage","createInitialMessage","toToolsJSONSchema","AssistantTransportOptions","AddMessageCommand","AddToolResultCommand","UserMessagePart","QueuedCommand","AssistantTransportCommand","SendCommandsRequestBody","useCommandQueue","createReplayBoundaryStream","useReplayRenderWait","useRunManager","useConvertedState","ToolExecutionStatus","createRequestHeaders","useRemoteThreadListRuntime","InMemoryThreadListAdapter","useAui","useAuiState","UserExternalState","convertAppendMessageToCommand","message","role","Error","parts","content","attachments","flatMap","a","contentPart","type","push","text","image","length","parentId","sourceId","symbolAssistantTransportExtras","Symbol","AssistantTransportExtras","sendCommand","command","state","asAssistantTransportExtras","extras","useAssistantTransportSendCommand","$","aui","t0","thread","getState","transportExtras","useAssistantTransportState","selector","T","t","s","useAssistantTransportThreadRuntime","options","agentStateRef","initialState","rerender","resumeFlagRef","isReplaying","setIsReplaying","waitForReplayRender","parentIdRef","undefined","commandQueue","onQueue","runManager","schedule","enqueueAppendMessage","console","warn","current","enqueue","startRun","threadId","threadListItem","remoteId","onRun","signal","AbortSignal","isResume","commands","flush","headers","bodyValue","body","context","runtime","getModelContext","requestBody","Record","system","tools","callSettings","config","prepareSendCommandsRequest","response","fetch","resumeApi","api","method","JSON","stringify","onResponse","ok","status","setReplaying","waitForRender","protocol","strict","decoder","err","stream","pipeThrough","initialMessage","unstable_state","throttle","onError","error","markedDelivered","chunk","metadata","markDelivered","prev","queued","onFinish","onCancel","cmds","inTransit","reset","updateState","updater","inTransitCmds","queuedCmds","toolStatuses","setToolStatuses","pendingCommands","converted","converter","isRunning","messages","isLoading","adapters","unstable_enableToolInvocations","onNew","Promise","capabilities","edit","onEdit","onReload","cancel","onResume","onAddToolResult","toolOptions","toolCallId","result","toolName","isError","artifact","modelContent","onLoadExternalState","useAssistantTransportRuntime","runtimeHook","RuntimeHook","adapter","allowNesting"],"sources":["../../../../src/legacy-runtime/runtime-cores/assistant-transport/useAssistantTransportRuntime.ts"],"sourcesContent":["\"use client\";\n\nimport type { AppendMessage } from \"@assistant-ui/core\";\nimport {\n type ReadonlyJSONObject,\n type ReadonlyJSONValue,\n asAsyncIterableStream,\n} from \"assistant-stream/utils\";\nimport { useExternalStoreRuntime } from \"../external-store/useExternalStoreRuntime\";\nimport type { AssistantRuntime } from \"../../runtime/AssistantRuntime\";\nimport type { AddToolResultOptions } from \"@assistant-ui/core\";\nimport { useMemo, useRef, useState } from \"react\";\nimport {\n AssistantMessageAccumulator,\n DataStreamDecoder,\n AssistantTransportDecoder,\n unstable_createInitialMessage as createInitialMessage,\n toToolsJSONSchema,\n} from \"assistant-stream\";\nimport type {\n AssistantTransportOptions,\n AddMessageCommand,\n AddToolResultCommand,\n UserMessagePart,\n QueuedCommand,\n AssistantTransportCommand,\n SendCommandsRequestBody,\n} from \"./types\";\nimport { useCommandQueue } from \"./commandQueue\";\nimport {\n createReplayBoundaryStream,\n useReplayRenderWait,\n} from \"./replayBoundaryStream\";\nimport { useRunManager } from \"./runManager\";\nimport { useConvertedState } from \"./useConvertedState\";\nimport type { ToolExecutionStatus } from \"@assistant-ui/core\";\nimport { createRequestHeaders } from \"@assistant-ui/core\";\nimport { useRemoteThreadListRuntime } from \"../remote-thread-list/useRemoteThreadListRuntime\";\nimport { InMemoryThreadListAdapter } from \"@assistant-ui/core\";\nimport { useAui, useAuiState } from \"@assistant-ui/store\";\nimport type { UserExternalState } from \"../../../augmentations\";\n\nconst convertAppendMessageToCommand = (\n message: AppendMessage,\n): AddMessageCommand | null => {\n if (message.role !== \"user\")\n throw new Error(\"Only user messages are supported\");\n\n const parts: UserMessagePart[] = [];\n const content = [\n ...message.content,\n ...(message.attachments?.flatMap((a) => a.content) ?? []),\n ];\n for (const contentPart of content) {\n if (contentPart.type === \"text\") {\n parts.push({ type: \"text\", text: contentPart.text });\n } else if (contentPart.type === \"image\") {\n parts.push({ type: \"image\", image: contentPart.image });\n }\n }\n\n if (parts.length === 0) return null;\n\n return {\n type: \"add-message\",\n message: {\n role: \"user\",\n parts,\n },\n parentId: message.parentId,\n sourceId: message.sourceId,\n };\n};\n\nconst symbolAssistantTransportExtras = Symbol(\"assistant-transport-extras\");\ntype AssistantTransportExtras = {\n [symbolAssistantTransportExtras]: true;\n sendCommand: (command: AssistantTransportCommand) => void;\n state: UserExternalState;\n};\n\nconst asAssistantTransportExtras = (\n extras: unknown,\n): AssistantTransportExtras => {\n if (\n typeof extras !== \"object\" ||\n extras == null ||\n !(symbolAssistantTransportExtras in extras)\n )\n throw new Error(\n \"This method can only be called when you are using useAssistantTransportRuntime\",\n );\n\n return extras as AssistantTransportExtras;\n};\n\nexport const useAssistantTransportSendCommand = () => {\n const aui = useAui();\n\n return (command: AssistantTransportCommand) => {\n const extras = aui.thread.getState().extras;\n const transportExtras = asAssistantTransportExtras(extras);\n transportExtras.sendCommand(command);\n };\n};\n\nexport function useAssistantTransportState(): UserExternalState;\nexport function useAssistantTransportState<T>(\n selector: (state: UserExternalState) => T,\n): T;\nexport function useAssistantTransportState<T>(\n selector: (state: UserExternalState) => T = (t) => t as T,\n): T | UserExternalState {\n return useAuiState((s) =>\n selector(asAssistantTransportExtras(s.thread.extras).state),\n );\n}\n\nconst useAssistantTransportThreadRuntime = <T>(\n options: AssistantTransportOptions<T>,\n): AssistantRuntime => {\n const agentStateRef = useRef(options.initialState);\n const [, rerender] = useState(0);\n const resumeFlagRef = useRef(false);\n const [isReplaying, setIsReplaying] = useState(false);\n const waitForReplayRender = useReplayRenderWait();\n const parentIdRef = useRef<string | null | undefined>(undefined);\n const commandQueue = useCommandQueue({\n onQueue: () => runManager.schedule(),\n });\n\n const enqueueAppendMessage = (message: AppendMessage) => {\n const command = convertAppendMessageToCommand(message);\n if (!command) {\n console.warn(\n \"[assistant-ui] Skipped add-message command with no supported parts\",\n );\n return;\n }\n parentIdRef.current = message.parentId;\n commandQueue.enqueue(command, {\n schedule: message.startRun ?? message.role === \"user\",\n });\n };\n\n const threadId = useAuiState((s) => s.threadListItem.remoteId);\n\n const runManager = useRunManager({\n onRun: async (signal: AbortSignal) => {\n const isResume = resumeFlagRef.current;\n resumeFlagRef.current = false;\n setIsReplaying(false);\n const commands: QueuedCommand[] = isResume ? [] : commandQueue.flush();\n if (commands.length === 0 && !isResume) return;\n\n // The flushed batch consumes the parentId; read it alongside the flush\n // (before any awaits) so a mid-run append keeps its own value. Resume\n // runs send no commands, so they neither send nor consume it.\n const parentId = isResume ? undefined : parentIdRef.current;\n if (!isResume) parentIdRef.current = undefined;\n\n const headers = await createRequestHeaders(options.headers);\n const bodyValue =\n typeof options.body === \"function\"\n ? await options.body()\n : options.body;\n const context = runtime.thread.getModelContext();\n\n let requestBody: Record<string, unknown> = {\n commands,\n state: agentStateRef.current,\n system: context.system,\n tools: context.tools ? toToolsJSONSchema(context.tools) : undefined,\n threadId,\n ...(parentId !== undefined && {\n parentId,\n }),\n // nested (new format, aligned with AssistantChatTransport)\n callSettings: context.callSettings,\n config: context.config,\n // @deprecated spread at top level — use nested `callSettings`/`config` instead. Will be removed in a future version.\n ...context.callSettings,\n ...context.config,\n ...(bodyValue ?? {}),\n };\n\n if (options.prepareSendCommandsRequest) {\n requestBody = await options.prepareSendCommandsRequest(\n requestBody as SendCommandsRequestBody,\n );\n }\n\n const response = await fetch(\n isResume ? options.resumeApi! : options.api,\n {\n method: \"POST\",\n headers,\n body: JSON.stringify(requestBody),\n signal,\n },\n );\n\n options.onResponse?.(response);\n\n if (!response.ok) {\n throw new Error(`Status ${response.status}: ${await response.text()}`);\n }\n\n if (!response.body) {\n throw new Error(\"Response body is null\");\n }\n\n const body = await createReplayBoundaryStream(response, {\n setReplaying: setIsReplaying,\n waitForRender: waitForReplayRender,\n });\n\n // Select decoder based on protocol option\n const protocol = options.protocol ?? \"data-stream\";\n // Resume replays a best-effort buffer; always reconcile leniently.\n const strict = isResume ? false : (options.strict ?? true);\n const decoder =\n protocol === \"assistant-transport\"\n ? new AssistantTransportDecoder({ strict })\n : new DataStreamDecoder({ strict });\n\n let err: string | undefined;\n const stream = body.pipeThrough(decoder).pipeThrough(\n new AssistantMessageAccumulator({\n initialMessage: createInitialMessage({\n unstable_state:\n (agentStateRef.current as ReadonlyJSONValue) ?? null,\n }),\n throttle: isResume,\n strict,\n onError: (error) => {\n err = error;\n },\n }),\n );\n\n let markedDelivered = false;\n\n for await (const chunk of asAsyncIterableStream(stream)) {\n if (chunk.metadata.unstable_state === agentStateRef.current) continue;\n\n if (!markedDelivered) {\n commandQueue.markDelivered();\n markedDelivered = true;\n }\n\n agentStateRef.current = chunk.metadata.unstable_state as T;\n rerender((prev) => prev + 1);\n }\n\n if (err) {\n throw new Error(err);\n }\n\n // A successful run confirms delivery even when no state-changing\n // chunk was observed.\n if (!markedDelivered) {\n commandQueue.markDelivered();\n }\n\n // commands that coalesced into this resume run must not starve\n if (isResume && commandQueue.state.queued.length > 0) {\n runManager.schedule();\n }\n },\n onFinish: options.onFinish,\n onCancel: () => {\n setIsReplaying(false);\n const cmds = [\n ...commandQueue.state.inTransit,\n ...commandQueue.state.queued,\n ];\n\n commandQueue.reset();\n\n options.onCancel?.({\n commands: cmds,\n updateState: (updater) => {\n agentStateRef.current = updater(agentStateRef.current);\n rerender((prev) => prev + 1);\n },\n });\n },\n onError: async (error) => {\n setIsReplaying(false);\n const inTransitCmds = [...commandQueue.state.inTransit];\n const queuedCmds = [...commandQueue.state.queued];\n\n commandQueue.reset();\n\n try {\n await options.onError?.(error as Error, {\n commands: inTransitCmds,\n updateState: (updater) => {\n agentStateRef.current = updater(agentStateRef.current);\n rerender((prev) => prev + 1);\n },\n });\n } finally {\n options.onCancel?.({\n commands: queuedCmds,\n updateState: (updater) => {\n agentStateRef.current = updater(agentStateRef.current);\n rerender((prev) => prev + 1);\n },\n error: error as Error,\n });\n }\n },\n });\n\n // Tool execution status state\n const [toolStatuses, setToolStatuses] = useState<\n Record<string, ToolExecutionStatus>\n >({});\n\n // Reactive conversion of agent state + connection metadata → UI state\n const pendingCommands = useMemo(\n () => [...commandQueue.state.inTransit, ...commandQueue.state.queued],\n [commandQueue.state],\n );\n const converted = useConvertedState(\n options.converter,\n agentStateRef.current,\n pendingCommands,\n runManager.isRunning,\n toolStatuses,\n );\n\n // Create runtime\n const runtime = useExternalStoreRuntime({\n messages: converted.messages,\n state: converted.state,\n isRunning: converted.isRunning,\n isLoading: isReplaying,\n adapters: options.adapters,\n unstable_enableToolInvocations: true,\n setToolStatuses,\n extras: {\n [symbolAssistantTransportExtras]: true,\n sendCommand: (command: AssistantTransportCommand) => {\n commandQueue.enqueue(command);\n },\n state: agentStateRef.current as UserExternalState,\n } satisfies AssistantTransportExtras,\n onNew: async (message: AppendMessage): Promise<void> =>\n enqueueAppendMessage(message),\n ...(options.capabilities?.edit && {\n onEdit: async (message: AppendMessage): Promise<void> =>\n enqueueAppendMessage(message),\n }),\n ...(commandQueue.state.queued.length > 0 && {\n onReload: async (parentId: string | null) => {\n parentIdRef.current = parentId;\n runManager.schedule();\n },\n }),\n onCancel: async () => {\n runManager.cancel();\n },\n onResume: async () => {\n if (!options.resumeApi)\n throw new Error(\"Must pass resumeApi to options to resume runs\");\n\n resumeFlagRef.current = true;\n runManager.schedule();\n },\n onAddToolResult: async (\n toolOptions: AddToolResultOptions,\n ): Promise<void> => {\n const command: AddToolResultCommand = {\n type: \"add-tool-result\",\n toolCallId: toolOptions.toolCallId,\n result: toolOptions.result as ReadonlyJSONObject,\n toolName: toolOptions.toolName,\n isError: toolOptions.isError,\n ...(toolOptions.artifact && { artifact: toolOptions.artifact }),\n ...(toolOptions.modelContent !== undefined && {\n modelContent: toolOptions.modelContent,\n }),\n };\n\n commandQueue.enqueue(command);\n },\n onLoadExternalState: async (state) => {\n agentStateRef.current = state as T;\n rerender((prev) => prev + 1);\n },\n });\n\n return runtime;\n};\n\n/**\n * @alpha This is an experimental API that is subject to change.\n */\nexport const useAssistantTransportRuntime = <T>(\n options: AssistantTransportOptions<T>,\n): AssistantRuntime => {\n const runtime = useRemoteThreadListRuntime({\n runtimeHook: function RuntimeHook() {\n return useAssistantTransportThreadRuntime(options);\n },\n adapter: new InMemoryThreadListAdapter(),\n allowNesting: true,\n });\n return runtime;\n};\n"],"mappings":"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"}
1
+ {"version":3,"file":"useAssistantTransportRuntime.js","names":["c","_c","AppendMessage","ReadonlyJSONObject","ReadonlyJSONValue","asAsyncIterableStream","useExternalStoreRuntime","AssistantRuntime","AddToolResultOptions","useMemo","useRef","useState","AssistantMessageAccumulator","DataStreamDecoder","AssistantTransportDecoder","unstable_createInitialMessage","createInitialMessage","toToolsJSONSchema","AssistantTransportOptions","AddMessageCommand","AddToolResultCommand","UserMessagePart","QueuedCommand","AssistantTransportCommand","SendCommandsRequestBody","useCommandQueue","createReplayBoundaryStream","useReplayRenderWait","useRunManager","useConvertedState","ToolExecutionStatus","createRequestHeaders","useRemoteThreadListRuntime","InMemoryThreadListAdapter","useAui","useAuiState","UserExternalState","convertAppendMessageToCommand","message","role","Error","parts","content","attachments","flatMap","a","contentPart","type","push","text","image","length","parentId","sourceId","readResumeState","response","Response","Promise","runId","state","T","status","ok","value","json","symbolAssistantTransportExtras","Symbol","AssistantTransportExtras","sendCommand","command","asAssistantTransportExtras","extras","useAssistantTransportSendCommand","$","aui","t0","thread","getState","transportExtras","useAssistantTransportState","selector","t","s","useAssistantTransportThreadRuntime","options","agentStateRef","initialState","rerender","resumeFlagRef","isReplaying","setIsReplaying","waitForReplayRender","parentIdRef","undefined","commandQueue","onQueue","runManager","schedule","enqueueAppendMessage","console","warn","current","enqueue","startRun","threadId","threadListItem","remoteId","onRun","signal","AbortSignal","isResume","commands","flush","headers","resumeState","resumeStateApi","resumeStateResponse","fetch","method","body","JSON","stringify","retained","queued","bodyValue","context","runtime","getModelContext","requestBody","Record","system","tools","callSettings","config","prepareSendCommandsRequest","resumeApi","api","onResponse","prev","setReplaying","waitForRender","protocol","strict","decoder","err","stream","pipeThrough","initialMessage","unstable_state","throttle","onError","error","markedDelivered","chunk","metadata","markDelivered","onFinish","onCancel","cmds","inTransit","reset","updateState","updater","inTransitCmds","queuedCmds","toolStatuses","setToolStatuses","pendingCommands","converted","converter","isRunning","messages","isLoading","adapters","unstable_enableToolInvocations","onNew","capabilities","edit","onEdit","onReload","cancel","onResume","onAddToolResult","toolOptions","toolCallId","result","toolName","isError","artifact","modelContent","onLoadExternalState","useAssistantTransportRuntime","runtimeHook","RuntimeHook","adapter","allowNesting"],"sources":["../../../../src/legacy-runtime/runtime-cores/assistant-transport/useAssistantTransportRuntime.ts"],"sourcesContent":["\"use client\";\n\nimport type { AppendMessage } from \"@assistant-ui/core\";\nimport {\n type ReadonlyJSONObject,\n type ReadonlyJSONValue,\n asAsyncIterableStream,\n} from \"assistant-stream/utils\";\nimport { useExternalStoreRuntime } from \"../external-store/useExternalStoreRuntime\";\nimport type { AssistantRuntime } from \"../../runtime/AssistantRuntime\";\nimport type { AddToolResultOptions } from \"@assistant-ui/core\";\nimport { useMemo, useRef, useState } from \"react\";\nimport {\n AssistantMessageAccumulator,\n DataStreamDecoder,\n AssistantTransportDecoder,\n unstable_createInitialMessage as createInitialMessage,\n toToolsJSONSchema,\n} from \"assistant-stream\";\nimport type {\n AssistantTransportOptions,\n AddMessageCommand,\n AddToolResultCommand,\n UserMessagePart,\n QueuedCommand,\n AssistantTransportCommand,\n SendCommandsRequestBody,\n} from \"./types\";\nimport { useCommandQueue } from \"./commandQueue\";\nimport {\n createReplayBoundaryStream,\n useReplayRenderWait,\n} from \"./replayBoundaryStream\";\nimport { useRunManager } from \"./runManager\";\nimport { useConvertedState } from \"./useConvertedState\";\nimport type { ToolExecutionStatus } from \"@assistant-ui/core\";\nimport { createRequestHeaders } from \"@assistant-ui/core\";\nimport { useRemoteThreadListRuntime } from \"../remote-thread-list/useRemoteThreadListRuntime\";\nimport { InMemoryThreadListAdapter } from \"@assistant-ui/core\";\nimport { useAui, useAuiState } from \"@assistant-ui/store\";\nimport type { UserExternalState } from \"../../../augmentations\";\n\nconst convertAppendMessageToCommand = (\n message: AppendMessage,\n): AddMessageCommand | null => {\n if (message.role !== \"user\")\n throw new Error(\"Only user messages are supported\");\n\n const parts: UserMessagePart[] = [];\n const content = [\n ...message.content,\n ...(message.attachments?.flatMap((a) => a.content) ?? []),\n ];\n for (const contentPart of content) {\n if (contentPart.type === \"text\") {\n parts.push({ type: \"text\", text: contentPart.text });\n } else if (contentPart.type === \"image\") {\n parts.push({ type: \"image\", image: contentPart.image });\n }\n }\n\n if (parts.length === 0) return null;\n\n return {\n type: \"add-message\",\n message: {\n role: \"user\",\n parts,\n },\n parentId: message.parentId,\n sourceId: message.sourceId,\n };\n};\n\nconst readResumeState = async <T>(\n response: Response,\n): Promise<{ runId: string; state: T } | null> => {\n if (response.status === 204) return null;\n if (!response.ok) {\n throw new Error(\n `Resume state request failed with status ${response.status}: ${await response.text()}`,\n );\n }\n\n let value: unknown;\n try {\n value = await response.json();\n } catch {\n throw new Error(\"Resume state response was not valid JSON\");\n }\n\n if (\n typeof value !== \"object\" ||\n value === null ||\n !(\"state\" in value) ||\n !(\"runId\" in value) ||\n typeof value.runId !== \"string\"\n ) {\n throw new Error(\"Resume state response must contain state and runId\");\n }\n\n return { runId: value.runId, state: value.state as T };\n};\n\nconst symbolAssistantTransportExtras = Symbol(\"assistant-transport-extras\");\ntype AssistantTransportExtras = {\n [symbolAssistantTransportExtras]: true;\n sendCommand: (command: AssistantTransportCommand) => void;\n state: UserExternalState;\n};\n\nconst asAssistantTransportExtras = (\n extras: unknown,\n): AssistantTransportExtras => {\n if (\n typeof extras !== \"object\" ||\n extras == null ||\n !(symbolAssistantTransportExtras in extras)\n )\n throw new Error(\n \"This method can only be called when you are using useAssistantTransportRuntime\",\n );\n\n return extras as AssistantTransportExtras;\n};\n\nexport const useAssistantTransportSendCommand = () => {\n const aui = useAui();\n\n return (command: AssistantTransportCommand) => {\n const extras = aui.thread.getState().extras;\n const transportExtras = asAssistantTransportExtras(extras);\n transportExtras.sendCommand(command);\n };\n};\n\nexport function useAssistantTransportState(): UserExternalState;\nexport function useAssistantTransportState<T>(\n selector: (state: UserExternalState) => T,\n): T;\nexport function useAssistantTransportState<T>(\n selector: (state: UserExternalState) => T = (t) => t as T,\n): T | UserExternalState {\n return useAuiState((s) =>\n selector(asAssistantTransportExtras(s.thread.extras).state),\n );\n}\n\nconst useAssistantTransportThreadRuntime = <T>(\n options: AssistantTransportOptions<T>,\n): AssistantRuntime => {\n const agentStateRef = useRef(options.initialState);\n const [, rerender] = useState(0);\n const resumeFlagRef = useRef(false);\n const [isReplaying, setIsReplaying] = useState(false);\n const waitForReplayRender = useReplayRenderWait();\n const parentIdRef = useRef<string | null | undefined>(undefined);\n const commandQueue = useCommandQueue({\n onQueue: () => runManager.schedule(),\n });\n\n const enqueueAppendMessage = (message: AppendMessage) => {\n const command = convertAppendMessageToCommand(message);\n if (!command) {\n console.warn(\n \"[assistant-ui] Skipped add-message command with no supported parts\",\n );\n return;\n }\n parentIdRef.current = message.parentId;\n commandQueue.enqueue(command, {\n schedule: message.startRun ?? message.role === \"user\",\n });\n };\n\n const threadId = useAuiState((s) => s.threadListItem.remoteId);\n\n const runManager = useRunManager({\n onRun: async (signal: AbortSignal) => {\n const isResume = resumeFlagRef.current;\n resumeFlagRef.current = false;\n setIsReplaying(false);\n const commands: QueuedCommand[] = isResume ? [] : commandQueue.flush();\n if (commands.length === 0 && !isResume) return;\n\n // The flushed batch consumes the parentId; read it alongside the flush\n // (before any awaits) so a mid-run append keeps its own value. Resume\n // runs send no commands, so they neither send nor consume it.\n const parentId = isResume ? undefined : parentIdRef.current;\n if (!isResume) parentIdRef.current = undefined;\n\n const headers = await createRequestHeaders(options.headers);\n let resumeState: { runId: string; state: T } | undefined;\n if (isResume && options.resumeStateApi) {\n const resumeStateResponse = await fetch(options.resumeStateApi, {\n method: \"POST\",\n headers,\n body: JSON.stringify({ threadId }),\n signal,\n });\n const retained = await readResumeState<T>(resumeStateResponse);\n if (retained === null) {\n if (commandQueue.state.queued.length > 0) {\n runManager.schedule();\n }\n return;\n }\n resumeState = retained;\n }\n\n const bodyValue =\n typeof options.body === \"function\"\n ? await options.body()\n : options.body;\n const context = runtime.thread.getModelContext();\n\n let requestBody: Record<string, unknown> = {\n commands,\n ...(resumeState === undefined && { state: agentStateRef.current }),\n system: context.system,\n tools: context.tools ? toToolsJSONSchema(context.tools) : undefined,\n threadId,\n ...(parentId !== undefined && {\n parentId,\n }),\n // nested (new format, aligned with AssistantChatTransport)\n callSettings: context.callSettings,\n config: context.config,\n // @deprecated spread at top level — use nested `callSettings`/`config` instead. Will be removed in a future version.\n ...context.callSettings,\n ...context.config,\n ...(bodyValue ?? {}),\n };\n\n if (options.prepareSendCommandsRequest) {\n requestBody = await options.prepareSendCommandsRequest(\n requestBody as SendCommandsRequestBody,\n );\n }\n\n if (resumeState !== undefined) {\n // The server replays a resume from the snapshot it retained for this\n // runId. Body overrides and prepare hooks can neither substitute a\n // state nor drop the ID the server validates against.\n requestBody = { ...requestBody, runId: resumeState.runId };\n delete requestBody[\"state\"];\n }\n\n const response = await fetch(\n isResume ? options.resumeApi! : options.api,\n {\n method: \"POST\",\n headers,\n body: JSON.stringify(requestBody),\n signal,\n },\n );\n\n options.onResponse?.(response);\n\n if (!response.ok) {\n throw new Error(`Status ${response.status}: ${await response.text()}`);\n }\n\n if (!response.body) {\n throw new Error(\"Response body is null\");\n }\n\n if (resumeState !== undefined) {\n agentStateRef.current = resumeState.state;\n rerender((prev) => prev + 1);\n }\n\n const body = await createReplayBoundaryStream(response, {\n setReplaying: setIsReplaying,\n waitForRender: waitForReplayRender,\n });\n\n // Select decoder based on protocol option\n const protocol = options.protocol ?? \"data-stream\";\n // Resume replays a best-effort buffer; always reconcile leniently.\n const strict = isResume ? false : (options.strict ?? true);\n const decoder =\n protocol === \"assistant-transport\"\n ? new AssistantTransportDecoder({ strict })\n : new DataStreamDecoder({ strict });\n\n let err: string | undefined;\n const stream = body.pipeThrough(decoder).pipeThrough(\n new AssistantMessageAccumulator({\n initialMessage: createInitialMessage({\n unstable_state:\n (agentStateRef.current as ReadonlyJSONValue) ?? null,\n }),\n throttle: isResume,\n strict,\n onError: (error) => {\n err = error;\n },\n }),\n );\n\n let markedDelivered = false;\n\n for await (const chunk of asAsyncIterableStream(stream)) {\n if (chunk.metadata.unstable_state === agentStateRef.current) continue;\n\n if (!markedDelivered) {\n commandQueue.markDelivered();\n markedDelivered = true;\n }\n\n agentStateRef.current = chunk.metadata.unstable_state as T;\n rerender((prev) => prev + 1);\n }\n\n if (err) {\n throw new Error(err);\n }\n\n // A successful run confirms delivery even when no state-changing\n // chunk was observed.\n if (!markedDelivered) {\n commandQueue.markDelivered();\n }\n\n // commands that coalesced into this resume run must not starve\n if (isResume && commandQueue.state.queued.length > 0) {\n runManager.schedule();\n }\n },\n onFinish: options.onFinish,\n onCancel: () => {\n setIsReplaying(false);\n const cmds = [\n ...commandQueue.state.inTransit,\n ...commandQueue.state.queued,\n ];\n\n commandQueue.reset();\n\n options.onCancel?.({\n commands: cmds,\n updateState: (updater) => {\n agentStateRef.current = updater(agentStateRef.current);\n rerender((prev) => prev + 1);\n },\n });\n },\n onError: async (error) => {\n setIsReplaying(false);\n const inTransitCmds = [...commandQueue.state.inTransit];\n const queuedCmds = [...commandQueue.state.queued];\n\n commandQueue.reset();\n\n try {\n await options.onError?.(error as Error, {\n commands: inTransitCmds,\n updateState: (updater) => {\n agentStateRef.current = updater(agentStateRef.current);\n rerender((prev) => prev + 1);\n },\n });\n } finally {\n options.onCancel?.({\n commands: queuedCmds,\n updateState: (updater) => {\n agentStateRef.current = updater(agentStateRef.current);\n rerender((prev) => prev + 1);\n },\n error: error as Error,\n });\n }\n },\n });\n\n // Tool execution status state\n const [toolStatuses, setToolStatuses] = useState<\n Record<string, ToolExecutionStatus>\n >({});\n\n // Reactive conversion of agent state + connection metadata → UI state\n const pendingCommands = useMemo(\n () => [...commandQueue.state.inTransit, ...commandQueue.state.queued],\n [commandQueue.state],\n );\n const converted = useConvertedState(\n options.converter,\n agentStateRef.current,\n pendingCommands,\n runManager.isRunning,\n toolStatuses,\n );\n\n // Create runtime\n const runtime = useExternalStoreRuntime({\n messages: converted.messages,\n state: converted.state,\n isRunning: converted.isRunning,\n isLoading: isReplaying,\n adapters: options.adapters,\n unstable_enableToolInvocations: true,\n setToolStatuses,\n extras: {\n [symbolAssistantTransportExtras]: true,\n sendCommand: (command: AssistantTransportCommand) => {\n commandQueue.enqueue(command);\n },\n state: agentStateRef.current as UserExternalState,\n } satisfies AssistantTransportExtras,\n onNew: async (message: AppendMessage): Promise<void> =>\n enqueueAppendMessage(message),\n ...(options.capabilities?.edit && {\n onEdit: async (message: AppendMessage): Promise<void> =>\n enqueueAppendMessage(message),\n }),\n ...(commandQueue.state.queued.length > 0 && {\n onReload: async (parentId: string | null) => {\n parentIdRef.current = parentId;\n runManager.schedule();\n },\n }),\n onCancel: async () => {\n runManager.cancel();\n },\n onResume: async () => {\n if (!options.resumeApi)\n throw new Error(\"Must pass resumeApi to options to resume runs\");\n\n resumeFlagRef.current = true;\n runManager.schedule();\n },\n onAddToolResult: async (\n toolOptions: AddToolResultOptions,\n ): Promise<void> => {\n const command: AddToolResultCommand = {\n type: \"add-tool-result\",\n toolCallId: toolOptions.toolCallId,\n result: toolOptions.result as ReadonlyJSONObject,\n toolName: toolOptions.toolName,\n isError: toolOptions.isError,\n ...(toolOptions.artifact && { artifact: toolOptions.artifact }),\n ...(toolOptions.modelContent !== undefined && {\n modelContent: toolOptions.modelContent,\n }),\n };\n\n commandQueue.enqueue(command);\n },\n onLoadExternalState: async (state) => {\n agentStateRef.current = state as T;\n rerender((prev) => prev + 1);\n },\n });\n\n return runtime;\n};\n\n/**\n * @alpha This is an experimental API that is subject to change.\n */\nexport const useAssistantTransportRuntime = <T>(\n options: AssistantTransportOptions<T>,\n): AssistantRuntime => {\n const runtime = useRemoteThreadListRuntime({\n runtimeHook: function RuntimeHook() {\n return useAssistantTransportThreadRuntime(options);\n },\n adapter: new InMemoryThreadListAdapter(),\n allowNesting: true,\n });\n return runtime;\n};\n"],"mappings":"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"}
@@ -32,7 +32,7 @@ const useActionBarExportMarkdown = (t0) => {
32
32
  a.href = url;
33
33
  a.download = filename ?? `message-${Date.now()}.md`;
34
34
  a.click();
35
- URL.revokeObjectURL(url);
35
+ setTimeout(() => URL.revokeObjectURL(url), 4e4);
36
36
  };
37
37
  $[2] = aui.message;
38
38
  $[3] = filename;
@@ -1 +1 @@
1
- {"version":3,"file":"ActionBarExportMarkdown.js","names":["c","_c","forwardRef","useCallback","ActionButtonProps","composeEventHandlers","Primitive","useAuiState","useAui","useActionBarExportMarkdown","t0","$","t1","undefined","filename","onExport","aui","hasExportableContent","_temp2","t2","message","content","getCopyText","blob","Blob","type","url","URL","createObjectURL","a","document","createElement","href","download","Date","now","click","revokeObjectURL","callback","ActionBarPrimitiveExportMarkdown","Element","HTMLButtonElement","Props","forwardedRef","disabled","onClick","props","t3","t4","t5","displayName","_temp","text","length","s","role","status","parts","some"],"sources":["../../../src/primitives/actionBar/ActionBarExportMarkdown.tsx"],"sourcesContent":["\"use client\";\n\nimport { forwardRef, useCallback } from \"react\";\nimport type { ActionButtonProps } from \"../../utils/createActionButton\";\nimport { composeEventHandlers } from \"@radix-ui/primitive\";\nimport { Primitive } from \"../../utils/Primitive\";\nimport { useAuiState, useAui } from \"@assistant-ui/store\";\n\nconst useActionBarExportMarkdown = ({\n filename,\n onExport,\n}: {\n filename?: string | undefined;\n onExport?: ((content: string) => void | Promise<void>) | undefined;\n} = {}) => {\n const aui = useAui();\n const hasExportableContent = useAuiState((s) => {\n return (\n (s.message.role !== \"assistant\" ||\n s.message.status?.type !== \"running\") &&\n s.message.parts.some((c) => c.type === \"text\" && c.text.length > 0)\n );\n });\n\n const callback = useCallback(async () => {\n const content = aui.message.getCopyText();\n if (!content) return;\n\n if (onExport) {\n await onExport(content);\n return;\n }\n\n const blob = new Blob([content], { type: \"text/markdown\" });\n const url = URL.createObjectURL(blob);\n const a = document.createElement(\"a\");\n a.href = url;\n a.download = filename ?? `message-${Date.now()}.md`;\n a.click();\n URL.revokeObjectURL(url);\n }, [aui, filename, onExport]);\n\n if (!hasExportableContent) return null;\n return callback;\n};\n\nexport namespace ActionBarPrimitiveExportMarkdown {\n export type Element = HTMLButtonElement;\n export type Props = ActionButtonProps<typeof useActionBarExportMarkdown>;\n}\n\nexport const ActionBarPrimitiveExportMarkdown = forwardRef<\n ActionBarPrimitiveExportMarkdown.Element,\n ActionBarPrimitiveExportMarkdown.Props\n>(({ filename, onExport, onClick, disabled, ...props }, forwardedRef) => {\n const callback = useActionBarExportMarkdown({ filename, onExport });\n return (\n <Primitive.button\n type=\"button\"\n {...props}\n ref={forwardedRef}\n disabled={disabled || !callback}\n onClick={composeEventHandlers(onClick, () => {\n callback?.();\n })}\n />\n );\n});\n\nActionBarPrimitiveExportMarkdown.displayName =\n \"ActionBarPrimitive.ExportMarkdown\";\n"],"mappings":"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"}
1
+ {"version":3,"file":"ActionBarExportMarkdown.js","names":["c","_c","forwardRef","useCallback","ActionButtonProps","composeEventHandlers","Primitive","useAuiState","useAui","useActionBarExportMarkdown","t0","$","t1","undefined","filename","onExport","aui","hasExportableContent","_temp2","t2","message","content","getCopyText","blob","Blob","type","url","URL","createObjectURL","a","document","createElement","href","download","Date","now","click","setTimeout","revokeObjectURL","callback","ActionBarPrimitiveExportMarkdown","Element","HTMLButtonElement","Props","forwardedRef","disabled","onClick","props","t3","t4","t5","displayName","_temp","text","length","s","role","status","parts","some"],"sources":["../../../src/primitives/actionBar/ActionBarExportMarkdown.tsx"],"sourcesContent":["\"use client\";\n\nimport { forwardRef, useCallback } from \"react\";\nimport type { ActionButtonProps } from \"../../utils/createActionButton\";\nimport { composeEventHandlers } from \"@radix-ui/primitive\";\nimport { Primitive } from \"../../utils/Primitive\";\nimport { useAuiState, useAui } from \"@assistant-ui/store\";\n\nconst useActionBarExportMarkdown = ({\n filename,\n onExport,\n}: {\n filename?: string | undefined;\n onExport?: ((content: string) => void | Promise<void>) | undefined;\n} = {}) => {\n const aui = useAui();\n const hasExportableContent = useAuiState((s) => {\n return (\n (s.message.role !== \"assistant\" ||\n s.message.status?.type !== \"running\") &&\n s.message.parts.some((c) => c.type === \"text\" && c.text.length > 0)\n );\n });\n\n const callback = useCallback(async () => {\n const content = aui.message.getCopyText();\n if (!content) return;\n\n if (onExport) {\n await onExport(content);\n return;\n }\n\n const blob = new Blob([content], { type: \"text/markdown\" });\n const url = URL.createObjectURL(blob);\n const a = document.createElement(\"a\");\n a.href = url;\n a.download = filename ?? `message-${Date.now()}.md`;\n a.click();\n setTimeout(() => URL.revokeObjectURL(url), 40_000);\n }, [aui, filename, onExport]);\n\n if (!hasExportableContent) return null;\n return callback;\n};\n\nexport namespace ActionBarPrimitiveExportMarkdown {\n export type Element = HTMLButtonElement;\n export type Props = ActionButtonProps<typeof useActionBarExportMarkdown>;\n}\n\nexport const ActionBarPrimitiveExportMarkdown = forwardRef<\n ActionBarPrimitiveExportMarkdown.Element,\n ActionBarPrimitiveExportMarkdown.Props\n>(({ filename, onExport, onClick, disabled, ...props }, forwardedRef) => {\n const callback = useActionBarExportMarkdown({ filename, onExport });\n return (\n <Primitive.button\n type=\"button\"\n {...props}\n ref={forwardedRef}\n disabled={disabled || !callback}\n onClick={composeEventHandlers(onClick, () => {\n callback?.();\n })}\n />\n );\n});\n\nActionBarPrimitiveExportMarkdown.displayName =\n \"ActionBarPrimitive.ExportMarkdown\";\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"AttachmentThumb.d.ts","names":[],"sources":["../../../src/primitives/attachment/AttachmentThumb.tsx"],"mappings":";;;KAUK,oBAAoB,gCAAgC,UAAU;kBAElD;OACH,UAAU,oBAAoB,UAAU;OACxC,QAAQ;;cAGT,0CAAwB,0BAAA,KAAA,qBAAA,gBAAA,kCAAA,eAAA;;;;oBAanC,cAAA,0CAAA,cAAA"}
1
+ {"version":3,"file":"AttachmentThumb.d.ts","names":[],"sources":["../../../src/primitives/attachment/AttachmentThumb.tsx"],"mappings":";;;KAUK,oBAAoB,gCAAgC,UAAU;kBAElD;OACH,UAAU,oBAAoB,UAAU;OACxC,QAAQ;;cAGT,0CAAwB,0BAAA,KAAA,qBAAA,gBAAA,kCAAA,eAAA;;;;oBAiBnC,cAAA,0CAAA,cAAA"}
@@ -3,29 +3,32 @@ import { Primitive } from "../../utils/Primitive.js";
3
3
  import { useAuiState } from "@assistant-ui/store";
4
4
  import { c } from "@assistant-ui/tap/react-shim/compiler-runtime";
5
5
  import { forwardRef } from "@assistant-ui/tap/react-shim";
6
- import { jsxs } from "react/jsx-runtime";
6
+ import { jsx } from "react/jsx-runtime";
7
7
  //#region src/primitives/attachment/AttachmentThumb.tsx
8
8
  const AttachmentPrimitiveThumb = forwardRef((props, ref) => {
9
9
  const $ = c(4);
10
- const ext = useAuiState(_temp);
11
- let t0;
12
- if ($[0] !== ext || $[1] !== props || $[2] !== ref) {
13
- t0 = /* @__PURE__ */ jsxs(Primitive.div, {
10
+ const label = useAuiState(_temp);
11
+ const t0 = props.children ?? label;
12
+ let t1;
13
+ if ($[0] !== props || $[1] !== ref || $[2] !== t0) {
14
+ t1 = /* @__PURE__ */ jsx(Primitive.div, {
14
15
  ...props,
15
16
  ref,
16
- children: [".", ext]
17
+ children: t0
17
18
  });
18
- $[0] = ext;
19
- $[1] = props;
20
- $[2] = ref;
21
- $[3] = t0;
22
- } else t0 = $[3];
23
- return t0;
19
+ $[0] = props;
20
+ $[1] = ref;
21
+ $[2] = t0;
22
+ $[3] = t1;
23
+ } else t1 = $[3];
24
+ return t1;
24
25
  });
25
26
  AttachmentPrimitiveThumb.displayName = "AttachmentPrimitive.unstable_Thumb";
26
27
  function _temp(s) {
27
- const parts = s.attachment.name.split(".");
28
- return parts.length > 1 ? parts.pop() : "";
28
+ const name = s.attachment.name;
29
+ const dot = name.lastIndexOf(".");
30
+ if (dot > 0 && dot < name.length - 1) return `.${name.slice(dot + 1)}`;
31
+ return s.attachment.type;
29
32
  }
30
33
  //#endregion
31
34
  export { AttachmentPrimitiveThumb };
@@ -1 +1 @@
1
- {"version":3,"file":"AttachmentThumb.js","names":["c","_c","ComponentPropsWithoutRef","forwardRef","ComponentRef","useAuiState","Primitive","PrimitiveDivProps","div","AttachmentPrimitiveThumb","Element","Props","props","ref","$","ext","_temp","t0","displayName","s","parts","attachment","name","split","length","pop"],"sources":["../../../src/primitives/attachment/AttachmentThumb.tsx"],"sourcesContent":["\"use client\";\n\nimport {\n type ComponentPropsWithoutRef,\n forwardRef,\n type ComponentRef,\n} from \"react\";\nimport { useAuiState } from \"@assistant-ui/store\";\nimport { Primitive } from \"../../utils/Primitive\";\n\ntype PrimitiveDivProps = ComponentPropsWithoutRef<typeof Primitive.div>;\n\nexport namespace AttachmentPrimitiveThumb {\n export type Element = ComponentRef<typeof Primitive.div>;\n export type Props = PrimitiveDivProps;\n}\n\nexport const AttachmentPrimitiveThumb = forwardRef<\n AttachmentPrimitiveThumb.Element,\n AttachmentPrimitiveThumb.Props\n>((props, ref) => {\n const ext = useAuiState((s) => {\n const parts = s.attachment.name.split(\".\");\n return parts.length > 1 ? parts.pop()! : \"\";\n });\n return (\n <Primitive.div {...props} ref={ref}>\n .{ext}\n </Primitive.div>\n );\n});\n\nAttachmentPrimitiveThumb.displayName = \"AttachmentPrimitive.unstable_Thumb\";\n"],"mappings":";;;;;;;AAiBA,MAAaS,2BAA2BN,YAGtCS,OAAAC,QAAA;CAAA,MAAAC,IAAAb,EAAA,CAAA;CACA,MAAAc,MAAYV,YAAYW,KAGvB;CAAE,IAAAC;CAAA,IAAAH,EAAA,OAAAC,OAAAD,EAAA,OAAAF,SAAAE,EAAA,OAAAD,KAAA;EAEDI,KAAA,qBAAA,UAAA,KAAA;GAAA,GAAmBL;GAAYC;GAA/B,UAAA,CAAoC,KAChCE,GACJ;;EAAgBD,EAAA,KAAAC;EAAAD,EAAA,KAAAF;EAAAE,EAAA,KAAAD;EAAAC,EAAA,KAAAG;CAAA,OAAAA,KAAAH,EAAA;CAAA,OAFhBG;AAEgB,CAEnB;AAEDR,yBAAyBS,cAAc;AAZrC,SAAAF,MAAAG,GAAA;CAEE,MAAAC,QAAcD,EAACE,WAAWC,KAAKC,MAAO,GAAG;CAAE,OACpCH,MAAKI,SAAU,IAAIJ,MAAKK,IAAW,IAAnC;AAAoC"}
1
+ {"version":3,"file":"AttachmentThumb.js","names":["c","_c","ComponentPropsWithoutRef","forwardRef","ComponentRef","useAuiState","Primitive","PrimitiveDivProps","div","AttachmentPrimitiveThumb","Element","Props","props","ref","$","label","_temp","t0","children","t1","displayName","s","name","attachment","dot","lastIndexOf","length","slice","type"],"sources":["../../../src/primitives/attachment/AttachmentThumb.tsx"],"sourcesContent":["\"use client\";\n\nimport {\n type ComponentPropsWithoutRef,\n forwardRef,\n type ComponentRef,\n} from \"react\";\nimport { useAuiState } from \"@assistant-ui/store\";\nimport { Primitive } from \"../../utils/Primitive\";\n\ntype PrimitiveDivProps = ComponentPropsWithoutRef<typeof Primitive.div>;\n\nexport namespace AttachmentPrimitiveThumb {\n export type Element = ComponentRef<typeof Primitive.div>;\n export type Props = PrimitiveDivProps;\n}\n\nexport const AttachmentPrimitiveThumb = forwardRef<\n AttachmentPrimitiveThumb.Element,\n AttachmentPrimitiveThumb.Props\n>((props, ref) => {\n const label = useAuiState((s) => {\n const name = s.attachment.name;\n const dot = name.lastIndexOf(\".\");\n if (dot > 0 && dot < name.length - 1) {\n return `.${name.slice(dot + 1)}`;\n }\n return s.attachment.type;\n });\n return (\n <Primitive.div {...props} ref={ref}>\n {props.children ?? label}\n </Primitive.div>\n );\n});\n\nAttachmentPrimitiveThumb.displayName = \"AttachmentPrimitive.unstable_Thumb\";\n"],"mappings":";;;;;;;AAiBA,MAAaS,2BAA2BN,YAGtCS,OAAAC,QAAA;CAAA,MAAAC,IAAAb,EAAA,CAAA;CACA,MAAAc,QAAcV,YAAYW,KAOzB;CAGI,MAAAC,KAAAL,MAAKM,YAALH;CAAuB,IAAAI;CAAA,IAAAL,EAAA,OAAAF,SAAAE,EAAA,OAAAD,OAAAC,EAAA,OAAAG,IAAA;EAD1BE,KAAA,oBAAA,UAAA,KAAA;GAAA,GAAmBP;GAAYC;GAC5BI,UAAAA;EACH,CAAA;EAAgBH,EAAA,KAAAF;EAAAE,EAAA,KAAAD;EAAAC,EAAA,KAAAG;EAAAH,EAAA,KAAAK;CAAA,OAAAA,KAAAL,EAAA;CAAA,OAFhBK;AAEgB,CAEnB;AAEDV,yBAAyBW,cAAc;AAhBrC,SAAAJ,MAAAK,GAAA;CAEE,MAAAC,OAAaD,EAACE,WAAWD;CACzB,MAAAE,MAAYF,KAAIG,YAAa,GAAG;CAChC,IAAID,MAAM,KAAKA,MAAMF,KAAII,SAAU,GAAC,OAC3B,IAAIJ,KAAIK,MAAOH,MAAM,CAAC;CAC9B,OACMH,EAACE,WAAWK;AAAK"}
@@ -1 +1 @@
1
- {"version":3,"file":"ComposerAttachmentDropzone.d.ts","names":[],"sources":["../../../src/primitives/composer/ComposerAttachmentDropzone.tsx"],"mappings":";;kBAgBiB;OACH,UAAU;OACV,QAAQ,MAAM,eAAe;IACvC;IACA,SAAS;IACT;;;cAIS,qCAAmC,MAAA,0BAAA,MAAA,eAAA;EANlC;EACD,SAAA;EACE;IA+Fb,MAAA,cAAA"}
1
+ {"version":3,"file":"ComposerAttachmentDropzone.d.ts","names":[],"sources":["../../../src/primitives/composer/ComposerAttachmentDropzone.tsx"],"mappings":";;kBAgBiB;OACH,UAAU;OACV,QAAQ,MAAM,eAAe;IACvC;IACA,SAAS;IACT;;;cAIS,qCAAmC,MAAA,0BAAA,MAAA,eAAA;EANlC;EACD,SAAA;EACE;IA8Gb,MAAA,cAAA"}
@@ -7,36 +7,48 @@ import { composeEventHandlers } from "@radix-ui/primitive";
7
7
  import { Slot } from "radix-ui";
8
8
  //#region src/primitives/composer/ComposerAttachmentDropzone.tsx
9
9
  const ComposerPrimitiveAttachmentDropzone = forwardRef((t0, ref) => {
10
- const $ = c(30);
10
+ const $ = c(32);
11
11
  const { disabled, asChild: t1, render, children, ...rest } = t0;
12
12
  const asChild = t1 === void 0 ? false : t1;
13
13
  const [isDragging, setIsDragging] = useState(false);
14
14
  const aui = useAui();
15
15
  let t2;
16
- if ($[0] !== disabled) {
16
+ if ($[0] !== aui || $[1] !== disabled) {
17
17
  t2 = (e) => {
18
18
  if (disabled) return;
19
+ if (!e.dataTransfer.types.includes("Files")) return;
19
20
  e.preventDefault();
21
+ if (!aui.thread.getState().capabilities.attachments) {
22
+ e.dataTransfer.dropEffect = "none";
23
+ return;
24
+ }
20
25
  setIsDragging(true);
21
26
  };
22
- $[0] = disabled;
23
- $[1] = t2;
24
- } else t2 = $[1];
27
+ $[0] = aui;
28
+ $[1] = disabled;
29
+ $[2] = t2;
30
+ } else t2 = $[2];
25
31
  const handleDragEnterCapture = t2;
26
32
  let t3;
27
- if ($[2] !== disabled || $[3] !== isDragging) {
33
+ if ($[3] !== aui || $[4] !== disabled || $[5] !== isDragging) {
28
34
  t3 = (e_0) => {
29
35
  if (disabled) return;
36
+ if (!e_0.dataTransfer.types.includes("Files")) return;
30
37
  e_0.preventDefault();
38
+ if (!aui.thread.getState().capabilities.attachments) {
39
+ e_0.dataTransfer.dropEffect = "none";
40
+ return;
41
+ }
31
42
  if (!isDragging) setIsDragging(true);
32
43
  };
33
- $[2] = disabled;
34
- $[3] = isDragging;
35
- $[4] = t3;
36
- } else t3 = $[4];
44
+ $[3] = aui;
45
+ $[4] = disabled;
46
+ $[5] = isDragging;
47
+ $[6] = t3;
48
+ } else t3 = $[6];
37
49
  const handleDragOverCapture = t3;
38
50
  let t4;
39
- if ($[5] !== disabled) {
51
+ if ($[7] !== disabled) {
40
52
  t4 = (e_1) => {
41
53
  if (disabled) return;
42
54
  e_1.preventDefault();
@@ -44,40 +56,42 @@ const ComposerPrimitiveAttachmentDropzone = forwardRef((t0, ref) => {
44
56
  if (next && e_1.currentTarget.contains(next)) return;
45
57
  setIsDragging(false);
46
58
  };
47
- $[5] = disabled;
48
- $[6] = t4;
49
- } else t4 = $[6];
59
+ $[7] = disabled;
60
+ $[8] = t4;
61
+ } else t4 = $[8];
50
62
  const handleDragLeaveCapture = t4;
51
63
  let t5;
52
- if ($[7] !== aui || $[8] !== disabled) {
64
+ if ($[9] !== aui || $[10] !== disabled) {
53
65
  t5 = async (e_2) => {
54
66
  if (disabled) return;
55
- e_2.preventDefault();
56
67
  setIsDragging(false);
68
+ if (!e_2.dataTransfer.types.includes("Files")) return;
69
+ e_2.preventDefault();
57
70
  const files = Array.from(e_2.dataTransfer.files);
71
+ if (!aui.thread.getState().capabilities.attachments || files.length === 0) return;
58
72
  await Promise.all(files.map(async (file) => {
59
73
  try {
60
74
  await aui.composer.addAttachment(file);
61
75
  } catch {}
62
76
  }));
63
77
  };
64
- $[7] = aui;
65
- $[8] = disabled;
66
- $[9] = t5;
67
- } else t5 = $[9];
78
+ $[9] = aui;
79
+ $[10] = disabled;
80
+ $[11] = t5;
81
+ } else t5 = $[11];
68
82
  const handleDrop = t5;
69
83
  let t6;
70
- if ($[10] !== isDragging) {
84
+ if ($[12] !== isDragging) {
71
85
  t6 = isDragging ? { "data-dragging": "true" } : null;
72
- $[10] = isDragging;
73
- $[11] = t6;
74
- } else t6 = $[11];
86
+ $[12] = isDragging;
87
+ $[13] = t6;
88
+ } else t6 = $[13];
75
89
  const t7 = composeEventHandlers(rest.onDragEnterCapture, handleDragEnterCapture);
76
90
  const t8 = composeEventHandlers(rest.onDragOverCapture, handleDragOverCapture);
77
91
  const t9 = composeEventHandlers(rest.onDragLeaveCapture, handleDragLeaveCapture);
78
92
  const t10 = composeEventHandlers(rest.onDropCapture, handleDrop);
79
93
  let t11;
80
- if ($[12] !== ref || $[13] !== rest || $[14] !== t10 || $[15] !== t6 || $[16] !== t7 || $[17] !== t8 || $[18] !== t9) {
94
+ if ($[14] !== ref || $[15] !== rest || $[16] !== t10 || $[17] !== t6 || $[18] !== t7 || $[19] !== t8 || $[20] !== t9) {
81
95
  t11 = {
82
96
  ...t6,
83
97
  ...rest,
@@ -87,49 +101,49 @@ const ComposerPrimitiveAttachmentDropzone = forwardRef((t0, ref) => {
87
101
  onDropCapture: t10,
88
102
  ref
89
103
  };
90
- $[12] = ref;
91
- $[13] = rest;
92
- $[14] = t10;
93
- $[15] = t6;
94
- $[16] = t7;
95
- $[17] = t8;
96
- $[18] = t9;
97
- $[19] = t11;
98
- } else t11 = $[19];
104
+ $[14] = ref;
105
+ $[15] = rest;
106
+ $[16] = t10;
107
+ $[17] = t6;
108
+ $[18] = t7;
109
+ $[19] = t8;
110
+ $[20] = t9;
111
+ $[21] = t11;
112
+ } else t11 = $[21];
99
113
  const mergedProps = t11;
100
114
  if (render && isValidElement(render)) {
101
115
  const t12 = children !== void 0 ? children : render.props.children;
102
116
  let t13;
103
- if ($[20] !== render || $[21] !== t12) {
117
+ if ($[22] !== render || $[23] !== t12) {
104
118
  t13 = cloneElement(render, void 0, t12);
105
- $[20] = render;
106
- $[21] = t12;
107
- $[22] = t13;
108
- } else t13 = $[22];
119
+ $[22] = render;
120
+ $[23] = t12;
121
+ $[24] = t13;
122
+ } else t13 = $[24];
109
123
  let t14;
110
- if ($[23] !== mergedProps || $[24] !== t13) {
124
+ if ($[25] !== mergedProps || $[26] !== t13) {
111
125
  t14 = /* @__PURE__ */ jsx(Slot.Root, {
112
126
  ...mergedProps,
113
127
  children: t13
114
128
  });
115
- $[23] = mergedProps;
116
- $[24] = t13;
117
- $[25] = t14;
118
- } else t14 = $[25];
129
+ $[25] = mergedProps;
130
+ $[26] = t13;
131
+ $[27] = t14;
132
+ } else t14 = $[27];
119
133
  return t14;
120
134
  }
121
135
  const Comp = asChild ? Slot.Root : "div";
122
136
  let t12;
123
- if ($[26] !== Comp || $[27] !== children || $[28] !== mergedProps) {
137
+ if ($[28] !== Comp || $[29] !== children || $[30] !== mergedProps) {
124
138
  t12 = /* @__PURE__ */ jsx(Comp, {
125
139
  ...mergedProps,
126
140
  children
127
141
  });
128
- $[26] = Comp;
129
- $[27] = children;
130
- $[28] = mergedProps;
131
- $[29] = t12;
132
- } else t12 = $[29];
142
+ $[28] = Comp;
143
+ $[29] = children;
144
+ $[30] = mergedProps;
145
+ $[31] = t12;
146
+ } else t12 = $[31];
133
147
  return t12;
134
148
  });
135
149
  ComposerPrimitiveAttachmentDropzone.displayName = "ComposerPrimitive.AttachmentDropzone";