@assistant-ui/react-native 0.1.1 → 0.1.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (108) hide show
  1. package/dist/context/AssistantContext.d.ts +3 -1
  2. package/dist/context/AssistantContext.d.ts.map +1 -1
  3. package/dist/context/AssistantContext.js +2 -2
  4. package/dist/context/AssistantContext.js.map +1 -1
  5. package/dist/context/index.d.ts +1 -1
  6. package/dist/context/index.d.ts.map +1 -1
  7. package/dist/context/index.js +1 -1
  8. package/dist/context/index.js.map +1 -1
  9. package/dist/context/providers/RuntimeAdapterProvider.d.ts +1 -15
  10. package/dist/context/providers/RuntimeAdapterProvider.d.ts.map +1 -1
  11. package/dist/context/providers/RuntimeAdapterProvider.js +1 -13
  12. package/dist/context/providers/RuntimeAdapterProvider.js.map +1 -1
  13. package/dist/index.d.ts +12 -13
  14. package/dist/index.d.ts.map +1 -1
  15. package/dist/index.js +12 -14
  16. package/dist/index.js.map +1 -1
  17. package/dist/primitive-hooks/index.d.ts +0 -2
  18. package/dist/primitive-hooks/index.d.ts.map +1 -1
  19. package/dist/primitive-hooks/index.js +0 -2
  20. package/dist/primitive-hooks/index.js.map +1 -1
  21. package/dist/primitive-hooks/useComposerCancel.js +1 -1
  22. package/dist/primitive-hooks/useComposerCancel.js.map +1 -1
  23. package/dist/primitive-hooks/useComposerSend.d.ts.map +1 -1
  24. package/dist/primitive-hooks/useComposerSend.js +1 -1
  25. package/dist/primitive-hooks/useComposerSend.js.map +1 -1
  26. package/dist/primitives/actionBar/index.d.ts +5 -5
  27. package/dist/primitives/actionBar/index.d.ts.map +1 -1
  28. package/dist/primitives/actionBar/index.js +5 -5
  29. package/dist/primitives/actionBar/index.js.map +1 -1
  30. package/dist/primitives/attachment/index.d.ts +4 -4
  31. package/dist/primitives/attachment/index.d.ts.map +1 -1
  32. package/dist/primitives/attachment/index.js +4 -4
  33. package/dist/primitives/attachment/index.js.map +1 -1
  34. package/dist/primitives/branchPicker/index.d.ts +4 -4
  35. package/dist/primitives/branchPicker/index.d.ts.map +1 -1
  36. package/dist/primitives/branchPicker/index.js +4 -4
  37. package/dist/primitives/branchPicker/index.js.map +1 -1
  38. package/dist/primitives/chainOfThought/index.d.ts +3 -3
  39. package/dist/primitives/chainOfThought/index.d.ts.map +1 -1
  40. package/dist/primitives/chainOfThought/index.js +3 -3
  41. package/dist/primitives/chainOfThought/index.js.map +1 -1
  42. package/dist/primitives/composer/ComposerInput.d.ts +10 -2
  43. package/dist/primitives/composer/ComposerInput.d.ts.map +1 -1
  44. package/dist/primitives/composer/ComposerInput.js +36 -4
  45. package/dist/primitives/composer/ComposerInput.js.map +1 -1
  46. package/dist/primitives/composer/index.d.ts +7 -10
  47. package/dist/primitives/composer/index.d.ts.map +1 -1
  48. package/dist/primitives/composer/index.js +7 -10
  49. package/dist/primitives/composer/index.js.map +1 -1
  50. package/dist/primitives/message/index.d.ts +5 -5
  51. package/dist/primitives/message/index.d.ts.map +1 -1
  52. package/dist/primitives/message/index.js +5 -5
  53. package/dist/primitives/message/index.js.map +1 -1
  54. package/dist/primitives/suggestion/index.d.ts +3 -3
  55. package/dist/primitives/suggestion/index.d.ts.map +1 -1
  56. package/dist/primitives/suggestion/index.js +3 -3
  57. package/dist/primitives/suggestion/index.js.map +1 -1
  58. package/dist/primitives/thread/ThreadMessages.d.ts +23 -6
  59. package/dist/primitives/thread/ThreadMessages.d.ts.map +1 -1
  60. package/dist/primitives/thread/ThreadMessages.js +56 -15
  61. package/dist/primitives/thread/ThreadMessages.js.map +1 -1
  62. package/dist/primitives/thread/index.d.ts +7 -7
  63. package/dist/primitives/thread/index.d.ts.map +1 -1
  64. package/dist/primitives/thread/index.js +7 -7
  65. package/dist/primitives/thread/index.js.map +1 -1
  66. package/dist/primitives/threadList/index.d.ts +3 -3
  67. package/dist/primitives/threadList/index.d.ts.map +1 -1
  68. package/dist/primitives/threadList/index.js +3 -3
  69. package/dist/primitives/threadList/index.js.map +1 -1
  70. package/dist/primitives/threadListItem/index.d.ts +6 -6
  71. package/dist/primitives/threadListItem/index.d.ts.map +1 -1
  72. package/dist/primitives/threadListItem/index.js +6 -6
  73. package/dist/primitives/threadListItem/index.js.map +1 -1
  74. package/dist/runtimes/RemoteThreadListHookInstanceManager.d.ts +1 -95
  75. package/dist/runtimes/RemoteThreadListHookInstanceManager.d.ts.map +1 -1
  76. package/dist/runtimes/RemoteThreadListHookInstanceManager.js +1 -109
  77. package/dist/runtimes/RemoteThreadListHookInstanceManager.js.map +1 -1
  78. package/dist/runtimes/RemoteThreadListThreadListRuntimeCore.d.ts +1 -112
  79. package/dist/runtimes/RemoteThreadListThreadListRuntimeCore.d.ts.map +1 -1
  80. package/dist/runtimes/RemoteThreadListThreadListRuntimeCore.js +1 -439
  81. package/dist/runtimes/RemoteThreadListThreadListRuntimeCore.js.map +1 -1
  82. package/dist/runtimes/useRemoteThreadListRuntime.d.ts +1 -3
  83. package/dist/runtimes/useRemoteThreadListRuntime.d.ts.map +1 -1
  84. package/dist/runtimes/useRemoteThreadListRuntime.js +1 -46
  85. package/dist/runtimes/useRemoteThreadListRuntime.js.map +1 -1
  86. package/package.json +6 -6
  87. package/src/context/AssistantContext.tsx +5 -3
  88. package/src/context/index.ts +4 -1
  89. package/src/context/providers/RuntimeAdapterProvider.tsx +5 -42
  90. package/src/index.ts +11 -20
  91. package/src/primitive-hooks/index.ts +0 -2
  92. package/src/primitive-hooks/useComposerCancel.ts +1 -1
  93. package/src/primitive-hooks/useComposerSend.ts +3 -1
  94. package/src/primitives/actionBar/index.ts +16 -7
  95. package/src/primitives/attachment/index.ts +14 -5
  96. package/src/primitives/branchPicker/index.ts +8 -8
  97. package/src/primitives/chainOfThought/index.ts +5 -5
  98. package/src/primitives/composer/ComposerInput.tsx +75 -5
  99. package/src/primitives/composer/index.ts +19 -19
  100. package/src/primitives/message/index.ts +13 -7
  101. package/src/primitives/suggestion/index.ts +6 -6
  102. package/src/primitives/thread/ThreadMessages.tsx +103 -29
  103. package/src/primitives/thread/index.ts +17 -11
  104. package/src/primitives/threadList/index.ts +12 -3
  105. package/src/primitives/threadListItem/index.ts +11 -11
  106. package/src/runtimes/RemoteThreadListHookInstanceManager.tsx +1 -180
  107. package/src/runtimes/RemoteThreadListThreadListRuntimeCore.tsx +1 -538
  108. package/src/runtimes/useRemoteThreadListRuntime.ts +1 -80
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@assistant-ui/react-native",
3
- "version": "0.1.1",
3
+ "version": "0.1.3",
4
4
  "description": "React Native bindings for assistant-ui",
5
5
  "keywords": [
6
6
  "assistant",
@@ -33,9 +33,9 @@
33
33
  ],
34
34
  "sideEffects": false,
35
35
  "dependencies": {
36
- "@assistant-ui/core": "^0.1.1",
37
- "@assistant-ui/store": "^0.2.1",
38
- "@assistant-ui/tap": "^0.5.1",
36
+ "@assistant-ui/core": "^0.1.3",
37
+ "@assistant-ui/store": "^0.2.2",
38
+ "@assistant-ui/tap": "^0.5.2",
39
39
  "assistant-stream": "^0.3.4",
40
40
  "zustand": "^5.0.11"
41
41
  },
@@ -52,9 +52,9 @@
52
52
  "devDependencies": {
53
53
  "@types/react": "^19.2.14",
54
54
  "react": "^19.2.4",
55
- "react-native": "^0.84.0",
55
+ "react-native": "^0.84.1",
56
56
  "vitest": "^4.0.18",
57
- "@assistant-ui/x-buildutils": "0.0.1"
57
+ "@assistant-ui/x-buildutils": "0.0.2"
58
58
  },
59
59
  "publishConfig": {
60
60
  "access": "public",
@@ -1,5 +1,5 @@
1
1
  import { type ReactNode, memo } from "react";
2
- import { useAui } from "@assistant-ui/store";
2
+ import { useAui, type AssistantClient } from "@assistant-ui/store";
3
3
  import type { AssistantRuntime } from "@assistant-ui/core";
4
4
  import { AssistantProviderBase } from "@assistant-ui/core/react";
5
5
 
@@ -14,16 +14,18 @@ export const useAssistantRuntime = (): AssistantRuntime => {
14
14
  return runtime;
15
15
  };
16
16
 
17
- export const AssistantProvider = memo(
17
+ export const AssistantRuntimeProvider = memo(
18
18
  ({
19
19
  runtime,
20
+ aui,
20
21
  children,
21
22
  }: {
22
23
  runtime: AssistantRuntime;
24
+ aui?: AssistantClient | null;
23
25
  children: ReactNode;
24
26
  }) => {
25
27
  return (
26
- <AssistantProviderBase runtime={runtime}>
28
+ <AssistantProviderBase runtime={runtime} aui={aui ?? null}>
27
29
  {children}
28
30
  </AssistantProviderBase>
29
31
  );
@@ -1 +1,4 @@
1
- export { AssistantProvider, useAssistantRuntime } from "./AssistantContext";
1
+ export {
2
+ AssistantRuntimeProvider,
3
+ useAssistantRuntime,
4
+ } from "./AssistantContext";
@@ -1,42 +1,5 @@
1
- import { createContext, FC, ReactNode, useContext } from "react";
2
- import type {
3
- ThreadHistoryAdapter,
4
- AttachmentAdapter,
5
- ModelContextProvider,
6
- } from "@assistant-ui/core";
7
-
8
- export type RuntimeAdapters = {
9
- modelContext?: ModelContextProvider | undefined;
10
- history?: ThreadHistoryAdapter | undefined;
11
- attachments?: AttachmentAdapter | undefined;
12
- };
13
-
14
- const RuntimeAdaptersContext = createContext<RuntimeAdapters | null>(null);
15
-
16
- export namespace RuntimeAdapterProvider {
17
- export type Props = {
18
- adapters: RuntimeAdapters;
19
- children: ReactNode;
20
- };
21
- }
22
-
23
- export const RuntimeAdapterProvider: FC<RuntimeAdapterProvider.Props> = ({
24
- adapters,
25
- children,
26
- }) => {
27
- const context = useContext(RuntimeAdaptersContext);
28
- return (
29
- <RuntimeAdaptersContext.Provider
30
- value={{
31
- ...context,
32
- ...adapters,
33
- }}
34
- >
35
- {children}
36
- </RuntimeAdaptersContext.Provider>
37
- );
38
- };
39
-
40
- export const useRuntimeAdapters = () => {
41
- return useContext(RuntimeAdaptersContext);
42
- };
1
+ export {
2
+ RuntimeAdapterProvider,
3
+ useRuntimeAdapters,
4
+ type RuntimeAdapters,
5
+ } from "@assistant-ui/core/react";
package/src/index.ts CHANGED
@@ -92,7 +92,7 @@ export {
92
92
  } from "@assistant-ui/store";
93
93
 
94
94
  // Context providers and hooks
95
- export { AssistantProvider, useAssistantRuntime } from "./context";
95
+ export { AssistantRuntimeProvider, useAssistantRuntime } from "./context";
96
96
 
97
97
  // Primitive hooks
98
98
  export {
@@ -109,8 +109,6 @@ export {
109
109
  useActionBarReload,
110
110
  useActionBarFeedbackPositive,
111
111
  useActionBarFeedbackNegative,
112
- useEditComposerSend,
113
- useEditComposerCancel,
114
112
  useComposerAddAttachment,
115
113
  } from "./primitive-hooks";
116
114
 
@@ -122,16 +120,16 @@ export {
122
120
  } from "./runtimes";
123
121
 
124
122
  // Primitives
125
- export * from "./primitives/thread";
126
- export * from "./primitives/composer";
127
- export * from "./primitives/message";
128
- export * from "./primitives/threadList";
129
- export * from "./primitives/actionBar";
130
- export * from "./primitives/branchPicker";
131
- export * from "./primitives/attachment";
132
- export * from "./primitives/threadListItem";
133
- export * from "./primitives/chainOfThought";
134
- export * from "./primitives/suggestion";
123
+ export * as ThreadPrimitive from "./primitives/thread";
124
+ export * as ComposerPrimitive from "./primitives/composer";
125
+ export * as MessagePrimitive from "./primitives/message";
126
+ export * as ThreadListPrimitive from "./primitives/threadList";
127
+ export * as ActionBarPrimitive from "./primitives/actionBar";
128
+ export * as BranchPickerPrimitive from "./primitives/branchPicker";
129
+ export * as AttachmentPrimitive from "./primitives/attachment";
130
+ export * as ThreadListItemPrimitive from "./primitives/threadListItem";
131
+ export * as ChainOfThoughtPrimitive from "./primitives/chainOfThought";
132
+ export * as SuggestionPrimitive from "./primitives/suggestion";
135
133
 
136
134
  // Re-export shared providers from core/react
137
135
  export {
@@ -148,10 +146,3 @@ export {
148
146
  export * from "./model-context";
149
147
  export * from "./client";
150
148
  export * from "./types";
151
-
152
- // Adapters
153
- export {
154
- type TitleGenerationAdapter,
155
- createSimpleTitleAdapter,
156
- createLocalStorageAdapter,
157
- } from "./adapters";
@@ -15,6 +15,4 @@ export {
15
15
  useActionBarFeedbackPositive,
16
16
  useActionBarFeedbackNegative,
17
17
  } from "./useActionBarFeedback";
18
- export { useEditComposerSend } from "./useEditComposerSend";
19
- export { useEditComposerCancel } from "./useEditComposerCancel";
20
18
  export { useComposerAddAttachment } from "./useComposerAddAttachment";
@@ -6,7 +6,7 @@ export const useComposerCancel = () => {
6
6
  const canCancel = useAuiState((s) => s.thread.isRunning);
7
7
 
8
8
  const cancel = useCallback(() => {
9
- aui.threads().thread("main").cancelRun();
9
+ aui.composer().cancel();
10
10
  }, [aui]);
11
11
 
12
12
  return { cancel, canCancel };
@@ -3,7 +3,9 @@ import { useAui, useAuiState } from "@assistant-ui/store";
3
3
 
4
4
  export const useComposerSend = () => {
5
5
  const aui = useAui();
6
- const canSend = useAuiState((s) => !s.composer.isEmpty);
6
+ const canSend = useAuiState(
7
+ (s) => !s.thread.isRunning && s.composer.isEditing && !s.composer.isEmpty,
8
+ );
7
9
 
8
10
  const send = useCallback(() => {
9
11
  aui.composer().send();
@@ -1,11 +1,20 @@
1
- export { ActionBarCopy, type ActionBarCopyProps } from "./ActionBarCopy";
2
- export { ActionBarEdit, type ActionBarEditProps } from "./ActionBarEdit";
3
- export { ActionBarReload, type ActionBarReloadProps } from "./ActionBarReload";
4
1
  export {
5
- ActionBarFeedbackPositive,
6
- type ActionBarFeedbackPositiveProps,
2
+ ActionBarCopy as Copy,
3
+ type ActionBarCopyProps as CopyProps,
4
+ } from "./ActionBarCopy";
5
+ export {
6
+ ActionBarEdit as Edit,
7
+ type ActionBarEditProps as EditProps,
8
+ } from "./ActionBarEdit";
9
+ export {
10
+ ActionBarReload as Reload,
11
+ type ActionBarReloadProps as ReloadProps,
12
+ } from "./ActionBarReload";
13
+ export {
14
+ ActionBarFeedbackPositive as FeedbackPositive,
15
+ type ActionBarFeedbackPositiveProps as FeedbackPositiveProps,
7
16
  } from "./ActionBarFeedbackPositive";
8
17
  export {
9
- ActionBarFeedbackNegative,
10
- type ActionBarFeedbackNegativeProps,
18
+ ActionBarFeedbackNegative as FeedbackNegative,
19
+ type ActionBarFeedbackNegativeProps as FeedbackNegativeProps,
11
20
  } from "./ActionBarFeedbackNegative";
@@ -1,7 +1,16 @@
1
- export { AttachmentRoot, type AttachmentRootProps } from "./AttachmentRoot";
2
- export { AttachmentName, type AttachmentNameProps } from "./AttachmentName";
3
- export { AttachmentThumb, type AttachmentThumbProps } from "./AttachmentThumb";
4
1
  export {
5
- AttachmentRemove,
6
- type AttachmentRemoveProps,
2
+ AttachmentRoot as Root,
3
+ type AttachmentRootProps as RootProps,
4
+ } from "./AttachmentRoot";
5
+ export {
6
+ AttachmentName as Name,
7
+ type AttachmentNameProps as NameProps,
8
+ } from "./AttachmentName";
9
+ export {
10
+ AttachmentThumb as Thumb,
11
+ type AttachmentThumbProps as ThumbProps,
12
+ } from "./AttachmentThumb";
13
+ export {
14
+ AttachmentRemove as Remove,
15
+ type AttachmentRemoveProps as RemoveProps,
7
16
  } from "./AttachmentRemove";
@@ -1,16 +1,16 @@
1
1
  export {
2
- BranchPickerPrevious,
3
- type BranchPickerPreviousProps,
2
+ BranchPickerPrevious as Previous,
3
+ type BranchPickerPreviousProps as PreviousProps,
4
4
  } from "./BranchPickerPrevious";
5
5
  export {
6
- BranchPickerNext,
7
- type BranchPickerNextProps,
6
+ BranchPickerNext as Next,
7
+ type BranchPickerNextProps as NextProps,
8
8
  } from "./BranchPickerNext";
9
9
  export {
10
- BranchPickerNumber,
11
- type BranchPickerNumberProps,
10
+ BranchPickerNumber as Number,
11
+ type BranchPickerNumberProps as NumberProps,
12
12
  } from "./BranchPickerNumber";
13
13
  export {
14
- BranchPickerCount,
15
- type BranchPickerCountProps,
14
+ BranchPickerCount as Count,
15
+ type BranchPickerCountProps as CountProps,
16
16
  } from "./BranchPickerCount";
@@ -1,9 +1,9 @@
1
1
  export {
2
- ChainOfThoughtRoot,
3
- type ChainOfThoughtRootProps,
2
+ ChainOfThoughtRoot as Root,
3
+ type ChainOfThoughtRootProps as RootProps,
4
4
  } from "./ChainOfThoughtRoot";
5
5
  export {
6
- ChainOfThoughtAccordionTrigger,
7
- type ChainOfThoughtAccordionTriggerProps,
6
+ ChainOfThoughtAccordionTrigger as AccordionTrigger,
7
+ type ChainOfThoughtAccordionTriggerProps as AccordionTriggerProps,
8
8
  } from "./ChainOfThoughtAccordionTrigger";
9
- export { ChainOfThoughtPrimitiveParts } from "@assistant-ui/core/react";
9
+ export { ChainOfThoughtPrimitiveParts as Parts } from "@assistant-ui/core/react";
@@ -1,12 +1,48 @@
1
- import { useCallback } from "react";
2
- import { TextInput, type TextInputProps } from "react-native";
1
+ import { useCallback, useEffect, useRef } from "react";
2
+ import {
3
+ Platform,
4
+ TextInput,
5
+ type NativeSyntheticEvent,
6
+ type TextInputKeyPressEventData,
7
+ type TextInputProps,
8
+ } from "react-native";
3
9
  import { useAui, useAuiState } from "@assistant-ui/store";
4
10
 
5
- export type ComposerInputProps = Omit<TextInputProps, "value" | "onChangeText">;
11
+ export type ComposerInputProps = Omit<
12
+ TextInputProps,
13
+ "value" | "onChangeText"
14
+ > & {
15
+ /**
16
+ * Controls how the Enter key submits messages (web only).
17
+ * - "enter": Plain Enter submits (Shift+Enter for newline)
18
+ * - "none": Enter inserts newline (no keyboard submission)
19
+ * @default "enter"
20
+ */
21
+ submitMode?: "enter" | "none";
22
+ };
23
+
24
+ const adjustWebTextareaHeight = (ref: React.RefObject<TextInput | null>) => {
25
+ if (Platform.OS !== "web") return;
26
+ // On web, the TextInput ref IS the DOM element
27
+ const el = ref.current as unknown as HTMLTextAreaElement | null;
28
+ if (!el) return;
29
+ // Ensure rows=1 so scrollHeight reflects actual content
30
+ if (el.rows !== 1) el.rows = 1;
31
+ el.style.overflow = "hidden";
32
+ el.style.height = "auto";
33
+ el.style.height = `${el.scrollHeight}px`;
34
+ };
6
35
 
7
- export const ComposerInput = (props: ComposerInputProps) => {
36
+ export const ComposerInput = ({
37
+ submitMode = "enter",
38
+ onKeyPress: onKeyPressProp,
39
+ numberOfLines,
40
+ style,
41
+ ...props
42
+ }: ComposerInputProps) => {
8
43
  const aui = useAui();
9
44
  const text = useAuiState((s) => s.composer.text);
45
+ const inputRef = useRef<TextInput>(null);
10
46
 
11
47
  const onChangeText = useCallback(
12
48
  (value: string) => {
@@ -15,5 +51,39 @@ export const ComposerInput = (props: ComposerInputProps) => {
15
51
  [aui],
16
52
  );
17
53
 
18
- return <TextInput value={text} onChangeText={onChangeText} {...props} />;
54
+ // Auto-resize textarea on web when text changes
55
+ useEffect(() => {
56
+ void text; // trigger re-run when text changes
57
+ adjustWebTextareaHeight(inputRef);
58
+ }, [text]);
59
+
60
+ const onKeyPress = useCallback(
61
+ (e: NativeSyntheticEvent<TextInputKeyPressEventData>) => {
62
+ onKeyPressProp?.(e);
63
+
64
+ if (Platform.OS !== "web") return;
65
+ if (submitMode !== "enter") return;
66
+
67
+ const nativeEvent = e.nativeEvent as TextInputKeyPressEventData & {
68
+ shiftKey?: boolean;
69
+ };
70
+ if (nativeEvent.key === "Enter" && !nativeEvent.shiftKey) {
71
+ (e as unknown as Event).preventDefault?.();
72
+ aui.composer().send();
73
+ }
74
+ },
75
+ [aui, submitMode, onKeyPressProp],
76
+ );
77
+
78
+ return (
79
+ <TextInput
80
+ ref={inputRef}
81
+ value={text}
82
+ onChangeText={onChangeText}
83
+ onKeyPress={onKeyPress}
84
+ numberOfLines={numberOfLines ?? (Platform.OS === "web" ? 1 : undefined)}
85
+ style={style}
86
+ {...props}
87
+ />
88
+ );
19
89
  };
@@ -1,25 +1,25 @@
1
- export { ComposerRoot, type ComposerRootProps } from "./ComposerRoot";
2
1
  export {
3
- ComposerAttachments,
4
- ComposerAttachmentByIndex,
2
+ ComposerRoot as Root,
3
+ type ComposerRootProps as RootProps,
4
+ } from "./ComposerRoot";
5
+ export {
6
+ ComposerAttachments as Attachments,
7
+ ComposerAttachmentByIndex as AttachmentByIndex,
5
8
  } from "./ComposerAttachments";
6
- export { ComposerInput, type ComposerInputProps } from "./ComposerInput";
7
- export { ComposerSend, type ComposerSendProps } from "./ComposerSend";
8
- export { ComposerCancel, type ComposerCancelProps } from "./ComposerCancel";
9
9
  export {
10
- ComposerAddAttachment,
11
- type ComposerAddAttachmentProps,
12
- } from "./ComposerAddAttachment";
13
- export { ComposerIf } from "./ComposerIf";
10
+ ComposerInput as Input,
11
+ type ComposerInputProps as InputProps,
12
+ } from "./ComposerInput";
14
13
  export {
15
- EditComposerInput,
16
- type EditComposerInputProps,
17
- } from "./EditComposerInput";
14
+ ComposerSend as Send,
15
+ type ComposerSendProps as SendProps,
16
+ } from "./ComposerSend";
18
17
  export {
19
- EditComposerSend,
20
- type EditComposerSendProps,
21
- } from "./EditComposerSend";
18
+ ComposerCancel as Cancel,
19
+ type ComposerCancelProps as CancelProps,
20
+ } from "./ComposerCancel";
22
21
  export {
23
- EditComposerCancel,
24
- type EditComposerCancelProps,
25
- } from "./EditComposerCancel";
22
+ ComposerAddAttachment as AddAttachment,
23
+ type ComposerAddAttachmentProps as AddAttachmentProps,
24
+ } from "./ComposerAddAttachment";
25
+ export { ComposerIf as If } from "./ComposerIf";
@@ -1,11 +1,17 @@
1
- export { MessageRoot, type MessageRootProps } from "./MessageRoot";
2
- export { MessageContent, type MessageContentProps } from "./MessageContent";
3
1
  export {
4
- MessagePrimitiveParts,
5
- MessagePrimitivePartByIndex,
2
+ MessageRoot as Root,
3
+ type MessageRootProps as RootProps,
4
+ } from "./MessageRoot";
5
+ export {
6
+ MessageContent as Content,
7
+ type MessageContentProps as ContentProps,
8
+ } from "./MessageContent";
9
+ export {
10
+ MessagePrimitiveParts as Parts,
11
+ MessagePrimitivePartByIndex as PartByIndex,
6
12
  } from "./MessageParts";
7
- export { MessageIf, type MessageIfProps } from "./MessageIf";
13
+ export { MessageIf as If, type MessageIfProps as IfProps } from "./MessageIf";
8
14
  export {
9
- MessageAttachments,
10
- MessageAttachmentByIndex,
15
+ MessageAttachments as Attachments,
16
+ MessageAttachmentByIndex as AttachmentByIndex,
11
17
  } from "./MessageAttachments";
@@ -1,12 +1,12 @@
1
1
  export {
2
- SuggestionTitle,
3
- type SuggestionTitleProps,
2
+ SuggestionTitle as Title,
3
+ type SuggestionTitleProps as TitleProps,
4
4
  } from "./SuggestionTitle";
5
5
  export {
6
- SuggestionDescription,
7
- type SuggestionDescriptionProps,
6
+ SuggestionDescription as Description,
7
+ type SuggestionDescriptionProps as DescriptionProps,
8
8
  } from "./SuggestionDescription";
9
9
  export {
10
- SuggestionTrigger,
11
- type SuggestionTriggerProps,
10
+ SuggestionTrigger as Trigger,
11
+ type SuggestionTriggerProps as TriggerProps,
12
12
  } from "./SuggestionTrigger";
@@ -1,51 +1,125 @@
1
- import { type ReactElement, useCallback } from "react";
1
+ import { type ComponentType, type FC, memo, useCallback } from "react";
2
2
  import { FlatList, type FlatListProps } from "react-native";
3
3
  import type { ThreadMessage } from "@assistant-ui/core";
4
- import { useAui, useAuiState, AuiProvider, Derived } from "@assistant-ui/store";
4
+ import { useAuiState } from "@assistant-ui/store";
5
+ import { MessageByIndexProvider } from "@assistant-ui/core/react";
6
+
7
+ type MessageComponents =
8
+ | {
9
+ Message: ComponentType;
10
+ EditComposer?: ComponentType | undefined;
11
+ UserEditComposer?: ComponentType | undefined;
12
+ AssistantEditComposer?: ComponentType | undefined;
13
+ SystemEditComposer?: ComponentType | undefined;
14
+ UserMessage?: ComponentType | undefined;
15
+ AssistantMessage?: ComponentType | undefined;
16
+ SystemMessage?: ComponentType | undefined;
17
+ }
18
+ | {
19
+ Message?: ComponentType | undefined;
20
+ EditComposer?: ComponentType | undefined;
21
+ UserEditComposer?: ComponentType | undefined;
22
+ AssistantEditComposer?: ComponentType | undefined;
23
+ SystemEditComposer?: ComponentType | undefined;
24
+ UserMessage: ComponentType;
25
+ AssistantMessage: ComponentType;
26
+ SystemMessage?: ComponentType | undefined;
27
+ };
5
28
 
6
29
  export type ThreadMessagesProps = Omit<
7
30
  FlatListProps<ThreadMessage>,
8
31
  "data" | "renderItem"
9
32
  > & {
10
- renderMessage: (props: {
11
- message: ThreadMessage;
12
- index: number;
13
- }) => ReactElement;
33
+ components: MessageComponents;
34
+ };
35
+
36
+ const DEFAULT_SYSTEM_MESSAGE = () => null;
37
+
38
+ const getComponent = (
39
+ components: MessageComponents,
40
+ role: ThreadMessage["role"],
41
+ isEditing: boolean,
42
+ ) => {
43
+ switch (role) {
44
+ case "user":
45
+ if (isEditing) {
46
+ return (
47
+ components.UserEditComposer ??
48
+ components.EditComposer ??
49
+ components.UserMessage ??
50
+ (components.Message as ComponentType)
51
+ );
52
+ } else {
53
+ return components.UserMessage ?? (components.Message as ComponentType);
54
+ }
55
+ case "assistant":
56
+ if (isEditing) {
57
+ return (
58
+ components.AssistantEditComposer ??
59
+ components.EditComposer ??
60
+ components.AssistantMessage ??
61
+ (components.Message as ComponentType)
62
+ );
63
+ } else {
64
+ return (
65
+ components.AssistantMessage ?? (components.Message as ComponentType)
66
+ );
67
+ }
68
+ case "system":
69
+ if (isEditing) {
70
+ return (
71
+ components.SystemEditComposer ??
72
+ components.EditComposer ??
73
+ components.SystemMessage ??
74
+ (components.Message as ComponentType)
75
+ );
76
+ } else {
77
+ return (
78
+ components.SystemMessage ??
79
+ (components.Message as ComponentType) ??
80
+ DEFAULT_SYSTEM_MESSAGE
81
+ );
82
+ }
83
+ default: {
84
+ const _exhaustiveCheck: never = role;
85
+ throw new Error(`Unknown message role: ${_exhaustiveCheck}`);
86
+ }
87
+ }
14
88
  };
15
89
 
16
- const MessageScope = ({
17
- index,
18
- children,
19
- }: {
20
- index: number;
21
- children: ReactElement;
90
+ const ThreadMessageComponent: FC<{ components: MessageComponents }> = ({
91
+ components,
22
92
  }) => {
23
- const aui = useAui({
24
- message: Derived({
25
- source: "thread",
26
- query: { type: "index", index },
27
- get: (aui) => aui.threads().thread("main").message({ index }),
28
- }),
29
- });
30
-
31
- return <AuiProvider value={aui}>{children}</AuiProvider>;
93
+ const role = useAuiState((s) => s.message.role);
94
+ const isEditing = useAuiState((s) => s.message.composer.isEditing);
95
+ const Component = getComponent(components, role, isEditing);
96
+
97
+ return <Component />;
32
98
  };
33
99
 
100
+ const ThreadMessageByIndex = memo(
101
+ ({ index, components }: { index: number; components: MessageComponents }) => {
102
+ return (
103
+ <MessageByIndexProvider index={index}>
104
+ <ThreadMessageComponent components={components} />
105
+ </MessageByIndexProvider>
106
+ );
107
+ },
108
+ (prev, next) =>
109
+ prev.index === next.index && prev.components === next.components,
110
+ );
111
+
34
112
  export const ThreadMessages = ({
35
- renderMessage,
113
+ components,
36
114
  ...flatListProps
37
115
  }: ThreadMessagesProps) => {
38
116
  const messages = useAuiState((s) => s.thread.messages);
39
117
 
40
118
  const renderItem = useCallback(
41
- ({ item, index }: { item: ThreadMessage; index: number }) => {
42
- return (
43
- <MessageScope index={index}>
44
- {renderMessage({ message: item as ThreadMessage, index })}
45
- </MessageScope>
46
- );
119
+ ({ index }: { item: ThreadMessage; index: number }) => {
120
+ return <ThreadMessageByIndex index={index} components={components} />;
47
121
  },
48
- [renderMessage],
122
+ [components],
49
123
  );
50
124
 
51
125
  const keyExtractor = useCallback((item: ThreadMessage) => item.id, []);
@@ -1,16 +1,22 @@
1
- export { ThreadRoot, type ThreadRootProps } from "./ThreadRoot";
2
- export { ThreadMessages, type ThreadMessagesProps } from "./ThreadMessages";
3
1
  export {
4
- ThreadPrimitiveMessages,
5
- ThreadPrimitiveMessageByIndex,
6
- } from "@assistant-ui/core/react";
7
- export { ThreadEmpty, type ThreadEmptyProps } from "./ThreadEmpty";
8
- export { ThreadIf, type ThreadIfProps } from "./ThreadIf";
2
+ ThreadRoot as Root,
3
+ type ThreadRootProps as RootProps,
4
+ } from "./ThreadRoot";
5
+ export {
6
+ ThreadMessages as Messages,
7
+ type ThreadMessagesProps as MessagesProps,
8
+ } from "./ThreadMessages";
9
+ export { ThreadPrimitiveMessageByIndex as MessageByIndex } from "@assistant-ui/core/react";
10
+ export {
11
+ ThreadEmpty as Empty,
12
+ type ThreadEmptyProps as EmptyProps,
13
+ } from "./ThreadEmpty";
14
+ export { ThreadIf as If, type ThreadIfProps as IfProps } from "./ThreadIf";
9
15
  export {
10
- ThreadSuggestion,
11
- type ThreadSuggestionProps,
16
+ ThreadSuggestion as Suggestion,
17
+ type ThreadSuggestionProps as SuggestionProps,
12
18
  } from "./ThreadSuggestion";
13
19
  export {
14
- ThreadPrimitiveSuggestions,
15
- ThreadPrimitiveSuggestionByIndex,
20
+ ThreadPrimitiveSuggestions as Suggestions,
21
+ ThreadPrimitiveSuggestionByIndex as SuggestionByIndex,
16
22
  } from "@assistant-ui/core/react";