@assistant-ui/react 0.14.14 → 0.14.16
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.
- package/README.md +5 -1
- package/dist/client/ExternalThread.d.ts +2 -12
- package/dist/client/ExternalThread.d.ts.map +1 -1
- package/dist/client/ExternalThread.js +30 -29
- package/dist/client/ExternalThread.js.map +1 -1
- package/dist/client/InMemoryThreadList.d.ts.map +1 -1
- package/dist/client/InMemoryThreadList.js +11 -10
- package/dist/client/InMemoryThreadList.js.map +1 -1
- package/dist/client/SingleThreadList.d.ts.map +1 -1
- package/dist/client/SingleThreadList.js +9 -8
- package/dist/client/SingleThreadList.js.map +1 -1
- package/dist/context/providers/ThreadViewportProvider.js +1 -1
- package/dist/context/providers/ThreadViewportProvider.js.map +1 -1
- package/dist/context/react/ThreadViewportContext.js +1 -1
- package/dist/context/react/utils/createContextHook.js +1 -1
- package/dist/context/react/utils/ensureBinding.js.map +1 -1
- package/dist/context/react/utils/useRuntimeState.js +1 -1
- package/dist/context/stores/ThreadViewport.js.map +1 -1
- package/dist/devtools/DevToolsHooks.js.map +1 -1
- package/dist/index.d.ts +4 -4
- package/dist/index.js +3 -3
- package/dist/legacy-runtime/AssistantRuntimeProvider.js +1 -1
- package/dist/legacy-runtime/cloud/auiV0.js +1 -1
- package/dist/legacy-runtime/hooks/AssistantContext.js.map +1 -1
- package/dist/legacy-runtime/hooks/AttachmentContext.js.map +1 -1
- package/dist/legacy-runtime/hooks/ComposerContext.js.map +1 -1
- package/dist/legacy-runtime/hooks/MessageContext.js.map +1 -1
- package/dist/legacy-runtime/hooks/MessagePartContext.js.map +1 -1
- package/dist/legacy-runtime/hooks/ThreadContext.js +1 -1
- package/dist/legacy-runtime/hooks/ThreadContext.js.map +1 -1
- package/dist/legacy-runtime/hooks/ThreadListItemContext.js.map +1 -1
- package/dist/legacy-runtime/runtime-cores/assistant-transport/commandQueue.js +1 -1
- package/dist/legacy-runtime/runtime-cores/assistant-transport/replayBoundaryStream.js +1 -1
- package/dist/legacy-runtime/runtime-cores/assistant-transport/runManager.js +1 -1
- package/dist/legacy-runtime/runtime-cores/assistant-transport/useAssistantTransportRuntime.js +1 -1
- package/dist/legacy-runtime/runtime-cores/assistant-transport/useAssistantTransportRuntime.js.map +1 -1
- package/dist/legacy-runtime/runtime-cores/assistant-transport/useConvertedState.js +1 -1
- package/dist/legacy-runtime/runtime-cores/assistant-transport/useLatestRef.js +1 -1
- package/dist/mcp-apps/McpAppRenderer.d.ts.map +1 -1
- package/dist/mcp-apps/McpAppRenderer.js +7 -7
- package/dist/mcp-apps/McpAppRenderer.js.map +1 -1
- package/dist/mcp-apps/McpAppsRemoteHost.d.ts.map +1 -1
- package/dist/mcp-apps/McpAppsRemoteHost.js +5 -4
- package/dist/mcp-apps/McpAppsRemoteHost.js.map +1 -1
- package/dist/mcp-apps/app-frame.d.ts +1 -1
- package/dist/mcp-apps/app-frame.d.ts.map +1 -1
- package/dist/mcp-apps/app-frame.js +82 -104
- package/dist/mcp-apps/app-frame.js.map +1 -1
- package/dist/mcp-apps/bridge.d.ts +3 -3
- package/dist/mcp-apps/bridge.d.ts.map +1 -1
- package/dist/mcp-apps/bridge.js +35 -10
- package/dist/mcp-apps/bridge.js.map +1 -1
- package/dist/mcp-apps/types.d.ts +2 -12
- package/dist/mcp-apps/types.d.ts.map +1 -1
- package/dist/mcp-apps/types.js.map +1 -1
- package/dist/model-context/frame/useAssistantFrameHost.js +1 -1
- package/dist/model-context/makeAssistantVisible.js +1 -1
- package/dist/model-context/makeAssistantVisible.js.map +1 -1
- package/dist/primitives/actionBar/ActionBarCopy.js +1 -1
- package/dist/primitives/actionBar/ActionBarExportMarkdown.js +1 -1
- package/dist/primitives/actionBar/ActionBarExportMarkdown.js.map +1 -1
- package/dist/primitives/actionBar/ActionBarFeedbackNegative.js +1 -1
- package/dist/primitives/actionBar/ActionBarFeedbackPositive.js +1 -1
- package/dist/primitives/actionBar/ActionBarInteractionContext.js +1 -1
- package/dist/primitives/actionBar/ActionBarRoot.js +1 -1
- package/dist/primitives/actionBar/ActionBarStopSpeaking.js +1 -1
- package/dist/primitives/actionBarMore/ActionBarMoreContent.js +1 -1
- package/dist/primitives/actionBarMore/ActionBarMoreItem.js +1 -1
- package/dist/primitives/actionBarMore/ActionBarMoreRoot.js +1 -1
- package/dist/primitives/actionBarMore/ActionBarMoreSeparator.js +1 -1
- package/dist/primitives/actionBarMore/ActionBarMoreTrigger.js +1 -1
- package/dist/primitives/assistantModal/AssistantModalAnchor.js +1 -1
- package/dist/primitives/assistantModal/AssistantModalContent.js +1 -1
- package/dist/primitives/assistantModal/AssistantModalRoot.js +1 -1
- package/dist/primitives/assistantModal/AssistantModalTrigger.js +1 -1
- package/dist/primitives/attachment/AttachmentRemove.js +1 -1
- package/dist/primitives/attachment/AttachmentRemove.js.map +1 -1
- package/dist/primitives/attachment/AttachmentRoot.js +1 -1
- package/dist/primitives/attachment/AttachmentThumb.js +1 -1
- package/dist/primitives/branchPicker/BranchPickerRoot.js +1 -1
- package/dist/primitives/chainOfThought/ChainOfThoughtAccordionTrigger.js +1 -1
- package/dist/primitives/chainOfThought/ChainOfThoughtAccordionTrigger.js.map +1 -1
- package/dist/primitives/chainOfThought/ChainOfThoughtRoot.js +1 -1
- package/dist/primitives/composer/ComposerAddAttachment.js +1 -1
- package/dist/primitives/composer/ComposerAddAttachment.js.map +1 -1
- package/dist/primitives/composer/ComposerAttachmentDropzone.js +1 -1
- package/dist/primitives/composer/ComposerAttachmentDropzone.js.map +1 -1
- package/dist/primitives/composer/ComposerDictationTranscript.js +1 -1
- package/dist/primitives/composer/ComposerInput.js +1 -1
- package/dist/primitives/composer/ComposerInput.js.map +1 -1
- package/dist/primitives/composer/ComposerInputPluginContext.js +1 -1
- package/dist/primitives/composer/ComposerQuote.js +1 -1
- package/dist/primitives/composer/ComposerQuote.js.map +1 -1
- package/dist/primitives/composer/ComposerRoot.js +1 -1
- package/dist/primitives/composer/ComposerSend.js +1 -1
- package/dist/primitives/composer/ComposerStopDictation.js +1 -1
- package/dist/primitives/composer/ComposerStopDictation.js.map +1 -1
- package/dist/primitives/composer/trigger/TriggerPopover.js +2 -2
- package/dist/primitives/composer/trigger/TriggerPopover.js.map +1 -1
- package/dist/primitives/composer/trigger/TriggerPopoverAction.js +1 -1
- package/dist/primitives/composer/trigger/TriggerPopoverBack.js +1 -1
- package/dist/primitives/composer/trigger/TriggerPopoverCategories.js +1 -1
- package/dist/primitives/composer/trigger/TriggerPopoverDirective.js +1 -1
- package/dist/primitives/composer/trigger/TriggerPopoverItems.js +1 -1
- package/dist/primitives/composer/trigger/TriggerPopoverResource.d.ts.map +1 -1
- package/dist/primitives/composer/trigger/TriggerPopoverResource.js +8 -7
- package/dist/primitives/composer/trigger/TriggerPopoverResource.js.map +1 -1
- package/dist/primitives/composer/trigger/TriggerPopoverRootContext.js +1 -1
- package/dist/primitives/composer/trigger/triggerDetectionResource.d.ts.map +1 -1
- package/dist/primitives/composer/trigger/triggerDetectionResource.js +5 -4
- package/dist/primitives/composer/trigger/triggerDetectionResource.js.map +1 -1
- package/dist/primitives/composer/trigger/triggerKeyboardResource.d.ts.map +1 -1
- package/dist/primitives/composer/trigger/triggerKeyboardResource.js +8 -7
- package/dist/primitives/composer/trigger/triggerKeyboardResource.js.map +1 -1
- package/dist/primitives/composer/trigger/triggerNavigationResource.d.ts.map +1 -1
- package/dist/primitives/composer/trigger/triggerNavigationResource.js +13 -12
- package/dist/primitives/composer/trigger/triggerNavigationResource.js.map +1 -1
- package/dist/primitives/composer/trigger/triggerSelectionResource.d.ts.map +1 -1
- package/dist/primitives/composer/trigger/triggerSelectionResource.js +7 -6
- package/dist/primitives/composer/trigger/triggerSelectionResource.js.map +1 -1
- package/dist/primitives/error/ErrorMessage.js +1 -1
- package/dist/primitives/error/ErrorRoot.js +1 -1
- package/dist/primitives/message/MessagePartsGrouped.js +1 -1
- package/dist/primitives/message/MessagePartsGrouped.js.map +1 -1
- package/dist/primitives/message/MessageRoot.js +1 -1
- package/dist/primitives/message/MessageRoot.js.map +1 -1
- package/dist/primitives/messagePart/MessagePartImage.js +1 -1
- package/dist/primitives/messagePart/MessagePartText.js +1 -1
- package/dist/primitives/queueItem/QueueItemRemove.js +1 -1
- package/dist/primitives/queueItem/QueueItemRemove.js.map +1 -1
- package/dist/primitives/queueItem/QueueItemSteer.js +1 -1
- package/dist/primitives/queueItem/QueueItemSteer.js.map +1 -1
- package/dist/primitives/queueItem/QueueItemText.js +1 -1
- package/dist/primitives/reasoning/useScrollLock.js +1 -1
- package/dist/primitives/reasoning/useScrollLock.js.map +1 -1
- package/dist/primitives/selectionToolbar/SelectionToolbarQuote.js +1 -1
- package/dist/primitives/selectionToolbar/SelectionToolbarQuote.js.map +1 -1
- package/dist/primitives/selectionToolbar/SelectionToolbarRoot.js +1 -1
- package/dist/primitives/selectionToolbar/SelectionToolbarRoot.js.map +1 -1
- package/dist/primitives/suggestion/SuggestionDescription.js +1 -1
- package/dist/primitives/suggestion/SuggestionTitle.js +1 -1
- package/dist/primitives/suggestion/SuggestionTrigger.js +1 -1
- package/dist/primitives/suggestion/SuggestionTrigger.js.map +1 -1
- package/dist/primitives/thread/ThreadRoot.js +1 -1
- package/dist/primitives/thread/ThreadScrollToBottom.js +1 -1
- package/dist/primitives/thread/ThreadScrollToBottom.js.map +1 -1
- package/dist/primitives/thread/ThreadViewport.js +1 -1
- package/dist/primitives/thread/ThreadViewport.js.map +1 -1
- package/dist/primitives/thread/ThreadViewportFooter.js +1 -1
- package/dist/primitives/thread/ThreadViewportFooter.js.map +1 -1
- package/dist/primitives/thread/topAnchor/topAnchorTurn.js.map +1 -1
- package/dist/primitives/thread/topAnchor/topAnchorUtils.js.map +1 -1
- package/dist/primitives/thread/topAnchor/useTopAnchorReserve.js +1 -1
- package/dist/primitives/thread/useThreadViewportAutoScroll.js +1 -1
- package/dist/primitives/thread/useThreadViewportAutoScroll.js.map +1 -1
- package/dist/primitives/threadList/ThreadListNew.js +1 -1
- package/dist/primitives/threadList/ThreadListRoot.js +1 -1
- package/dist/primitives/threadListItem/ThreadListItemRoot.js +1 -1
- package/dist/primitives/threadListItemMore/ThreadListItemMoreContent.js +1 -1
- package/dist/primitives/threadListItemMore/ThreadListItemMoreItem.js +1 -1
- package/dist/primitives/threadListItemMore/ThreadListItemMoreSeparator.js +1 -1
- package/dist/primitives/threadListItemMore/ThreadListItemMoreTrigger.js +1 -1
- package/dist/sandbox-host/SandboxHost.d.ts +50 -0
- package/dist/sandbox-host/SandboxHost.d.ts.map +1 -0
- package/dist/sandbox-host/SandboxHost.js +85 -0
- package/dist/sandbox-host/SandboxHost.js.map +1 -0
- package/dist/unstable/useMentionAdapter.js +1 -1
- package/dist/unstable/useMentionAdapter.js.map +1 -1
- package/dist/unstable/useSlashCommandAdapter.js +1 -1
- package/dist/unstable/useSlashCommandAdapter.js.map +1 -1
- package/dist/utils/Primitive.js +1 -1
- package/dist/utils/createActionButton.js +1 -1
- package/dist/utils/createActionButton.js.map +1 -1
- package/dist/utils/hooks/useManagedRef.js +1 -1
- package/dist/utils/hooks/useMediaQuery.js +1 -1
- package/dist/utils/hooks/useMediaQuery.js.map +1 -1
- package/dist/utils/hooks/useOnResizeContent.js +1 -1
- package/dist/utils/hooks/useOnScrollToBottom.js +1 -1
- package/dist/utils/hooks/useSizeHandle.js +1 -1
- package/dist/utils/json/is-json.js.map +1 -1
- package/dist/utils/smooth/SmoothContext.js +1 -1
- package/dist/utils/smooth/SmoothContext.js.map +1 -1
- package/dist/utils/smooth/useSmooth.js +1 -1
- package/dist/utils/smooth/useSmooth.js.map +1 -1
- package/dist/utils/useToolArgsFieldStatus.d.ts +2 -2
- package/dist/utils/useToolArgsFieldStatus.d.ts.map +1 -1
- package/package.json +48 -40
- package/src/client/ExternalThread.ts +484 -515
- package/src/client/InMemoryThreadList.ts +153 -162
- package/src/client/SingleThreadList.ts +87 -84
- package/src/context/providers/ThreadViewportProvider.tsx +2 -2
- package/src/index.ts +8 -1
- package/src/mcp-apps/McpAppRenderer.tsx +28 -35
- package/src/mcp-apps/McpAppsRemoteHost.ts +25 -24
- package/src/mcp-apps/app-frame.tsx +100 -141
- package/src/mcp-apps/bridge.test.ts +100 -60
- package/src/mcp-apps/bridge.ts +43 -21
- package/src/mcp-apps/types.ts +2 -12
- package/src/primitives/composer/trigger/TriggerPopover.tsx +1 -1
- package/src/primitives/composer/trigger/TriggerPopoverResource.ts +75 -76
- package/src/primitives/composer/trigger/triggerDetectionResource.ts +6 -5
- package/src/primitives/composer/trigger/triggerKeyboardResource.ts +9 -13
- package/src/primitives/composer/trigger/triggerNavigationResource.ts +14 -19
- package/src/primitives/composer/trigger/triggerSelectionResource.ts +8 -7
- package/src/sandbox-host/SandboxHost.test.tsx +231 -0
- package/src/sandbox-host/SandboxHost.tsx +185 -0
- package/src/tests/local-runtime-queue.test.tsx +305 -0
package/README.md
CHANGED
|
@@ -1,5 +1,9 @@
|
|
|
1
1
|
<a href="https://www.assistant-ui.com">
|
|
2
|
-
<
|
|
2
|
+
<picture>
|
|
3
|
+
<source media="(prefers-color-scheme: dark)" srcset="https://raw.githubusercontent.com/assistant-ui/assistant-ui/main/.github/assets/header-dark.svg" />
|
|
4
|
+
<source media="(prefers-color-scheme: light)" srcset="https://raw.githubusercontent.com/assistant-ui/assistant-ui/main/.github/assets/header.svg" />
|
|
5
|
+
<img src="https://raw.githubusercontent.com/assistant-ui/assistant-ui/main/.github/assets/header.svg" alt="assistant-ui Header" width="100%" />
|
|
6
|
+
</picture>
|
|
3
7
|
</a>
|
|
4
8
|
|
|
5
9
|
<p align="center">
|
|
@@ -1,20 +1,10 @@
|
|
|
1
1
|
import { ClientOutput } from "@assistant-ui/store";
|
|
2
|
-
import { AppendMessage, ThreadMessage } from "@assistant-ui/core";
|
|
3
|
-
import { QueueItemState } from "@assistant-ui/core/store";
|
|
2
|
+
import { AppendMessage, ExternalThreadQueueAdapter, ThreadMessage } from "@assistant-ui/core";
|
|
4
3
|
|
|
5
4
|
//#region src/client/ExternalThread.d.ts
|
|
6
5
|
type ExternalThreadMessage = ThreadMessage & {
|
|
7
6
|
id: string;
|
|
8
7
|
};
|
|
9
|
-
type ExternalThreadQueueAdapter = {
|
|
10
|
-
/** The current queue items. */items: readonly QueueItemState[]; /** Called when a message is submitted via the composer. Receives the steer preference. */
|
|
11
|
-
enqueue: (message: AppendMessage, opts: {
|
|
12
|
-
steer: boolean;
|
|
13
|
-
}) => void; /** Called to promote an existing queue item (cancel current run, run this immediately). */
|
|
14
|
-
steer: (queueItemId: string) => void; /** Called to remove an item from the queue. */
|
|
15
|
-
remove: (queueItemId: string) => void; /** Called to clear all pending queue items, with the reason for clearing. */
|
|
16
|
-
clear: (reason: "edit" | "reload" | "cancel-run") => void;
|
|
17
|
-
};
|
|
18
8
|
type ExternalThreadProps = {
|
|
19
9
|
messages: readonly ExternalThreadMessage[];
|
|
20
10
|
isRunning?: boolean;
|
|
@@ -38,5 +28,5 @@ type ExternalThreadProps = {
|
|
|
38
28
|
};
|
|
39
29
|
declare const ExternalThread: (props: ExternalThreadProps) => import("@assistant-ui/tap").ResourceElement<ClientOutput<"thread">, ExternalThreadProps>;
|
|
40
30
|
//#endregion
|
|
41
|
-
export { ExternalThread, ExternalThreadMessage, ExternalThreadProps
|
|
31
|
+
export { ExternalThread, ExternalThreadMessage, ExternalThreadProps };
|
|
42
32
|
//# sourceMappingURL=ExternalThread.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ExternalThread.d.ts","names":[],"sources":["../../src/client/ExternalThread.ts"],"mappings":"
|
|
1
|
+
{"version":3,"file":"ExternalThread.d.ts","names":[],"sources":["../../src/client/ExternalThread.ts"],"mappings":";;;;KA4BY,qBAAA,GAAwB,aAAa;EAC/C,EAAE;AAAA;AAAA,KAGQ,mBAAA;EACV,QAAA,WAAmB,qBAAA;EACnB,SAAA;EALE;AAGJ;;;;;EASE,cAAA;EAWQ;;;;EANR,KAAA,IAAS,OAAA,EAAS,aAAA;EAClB,MAAA,IAAU,OAAA,EAAS,aAAA;EACnB,QAAA,IAAY,QAAA;EACZ,UAAA;EACA,QAAA,eAJS;EAMT,KAAA,GAAQ,0BAAA;AAAA;AAAA,cAqYG,cAAA,GAAc,KAAA,EAAA,mBAAA,iCAAA,eAAA,CAAA,YAAA,YAAA,mBAAA"}
|
|
@@ -1,16 +1,17 @@
|
|
|
1
1
|
import { SingleThreadList } from "./SingleThreadList.js";
|
|
2
|
-
import { Derived, attachTransformScopes,
|
|
2
|
+
import { Derived, attachTransformScopes, useClientLookup, useClientResource } from "@assistant-ui/store";
|
|
3
3
|
import { DataRenderers, Tools } from "@assistant-ui/core/react";
|
|
4
|
+
import { useEffect, useEffectEvent, useMemo, useState } from "@assistant-ui/tap/react-shim";
|
|
4
5
|
import { ModelContext, Suggestions } from "@assistant-ui/core/store";
|
|
5
|
-
import { resource,
|
|
6
|
+
import { resource, withKey } from "@assistant-ui/tap";
|
|
6
7
|
//#region src/client/ExternalThread.ts
|
|
7
8
|
const EMPTY_QUEUE_ITEMS = [];
|
|
8
|
-
const MessageClient = resource(({ message, index, onEdit, onReload, queue })
|
|
9
|
-
const [isCopied, setIsCopied] =
|
|
10
|
-
const [isHovering, setIsHovering] =
|
|
11
|
-
const [isEditing, setIsEditing] =
|
|
12
|
-
const partClients =
|
|
13
|
-
const attachmentClients =
|
|
9
|
+
const MessageClient = resource(function MessageClient({ message, index, onEdit, onReload, queue }) {
|
|
10
|
+
const [isCopied, setIsCopied] = useState(false);
|
|
11
|
+
const [isHovering, setIsHovering] = useState(false);
|
|
12
|
+
const [isEditing, setIsEditing] = useState(false);
|
|
13
|
+
const partClients = useClientLookup(() => message.content.map((part, idx) => withKey(idx, PartResource({ part }))), [message.content]);
|
|
14
|
+
const attachmentClients = useClientLookup(() => (message.attachments ?? []).map((attachment) => withKey(attachment.id, AttachmentResource({
|
|
14
15
|
attachment,
|
|
15
16
|
onRemove: () => {}
|
|
16
17
|
}))), [message.attachments]);
|
|
@@ -29,7 +30,7 @@ const MessageClient = resource(({ message, index, onEdit, onReload, queue }) =>
|
|
|
29
30
|
});
|
|
30
31
|
setIsEditing(false);
|
|
31
32
|
};
|
|
32
|
-
const composerClient =
|
|
33
|
+
const composerClient = useClientResource(ComposerClientResource({
|
|
33
34
|
type: "edit",
|
|
34
35
|
isEditing,
|
|
35
36
|
canCancel: true,
|
|
@@ -39,7 +40,7 @@ const MessageClient = resource(({ message, index, onEdit, onReload, queue }) =>
|
|
|
39
40
|
message,
|
|
40
41
|
queue
|
|
41
42
|
}));
|
|
42
|
-
const state =
|
|
43
|
+
const state = useMemo(() => {
|
|
43
44
|
return {
|
|
44
45
|
...message,
|
|
45
46
|
attachments: message.attachments ?? [],
|
|
@@ -86,8 +87,8 @@ const MessageClient = resource(({ message, index, onEdit, onReload, queue }) =>
|
|
|
86
87
|
setIsHovering
|
|
87
88
|
};
|
|
88
89
|
});
|
|
89
|
-
const PartResource = resource(({ part })
|
|
90
|
-
const state =
|
|
90
|
+
const PartResource = resource(function PartResource({ part }) {
|
|
91
|
+
const state = useMemo(() => ({
|
|
91
92
|
...part,
|
|
92
93
|
status: { type: "complete" }
|
|
93
94
|
}), [part]);
|
|
@@ -98,7 +99,7 @@ const PartResource = resource(({ part }) => {
|
|
|
98
99
|
respondToToolApproval: () => {}
|
|
99
100
|
};
|
|
100
101
|
});
|
|
101
|
-
const AttachmentResource = resource(({ attachment, onRemove })
|
|
102
|
+
const AttachmentResource = resource(function AttachmentResource({ attachment, onRemove }) {
|
|
102
103
|
return {
|
|
103
104
|
getState: () => attachment,
|
|
104
105
|
remove: async () => {
|
|
@@ -106,42 +107,42 @@ const AttachmentResource = resource(({ attachment, onRemove }) => {
|
|
|
106
107
|
}
|
|
107
108
|
};
|
|
108
109
|
});
|
|
109
|
-
const QueueItemClient = resource(({ item, onSteer, onRemove })
|
|
110
|
+
const QueueItemClient = resource(function QueueItemClient({ item, onSteer, onRemove }) {
|
|
110
111
|
return {
|
|
111
112
|
getState: () => item,
|
|
112
113
|
steer: onSteer,
|
|
113
114
|
remove: onRemove
|
|
114
115
|
};
|
|
115
116
|
});
|
|
116
|
-
const ComposerClientResource = resource(({ type, isEditing, canCancel, isSendDisabled = false, onCancel, onBeginEdit, onSend, message, queue })
|
|
117
|
-
const [text, setText] =
|
|
118
|
-
const [role, setRole] =
|
|
119
|
-
const [runConfig, setRunConfig] =
|
|
120
|
-
const [attachments, setAttachments] =
|
|
121
|
-
const [quote, setQuote] =
|
|
122
|
-
const updateFromMessage =
|
|
117
|
+
const ComposerClientResource = resource(function ComposerClientResource({ type, isEditing, canCancel, isSendDisabled = false, onCancel, onBeginEdit, onSend, message, queue }) {
|
|
118
|
+
const [text, setText] = useState("");
|
|
119
|
+
const [role, setRole] = useState("user");
|
|
120
|
+
const [runConfig, setRunConfig] = useState({});
|
|
121
|
+
const [attachments, setAttachments] = useState([]);
|
|
122
|
+
const [quote, setQuote] = useState(void 0);
|
|
123
|
+
const updateFromMessage = useEffectEvent(() => {
|
|
123
124
|
if (message) {
|
|
124
125
|
setText(message.content.filter((part) => part.type === "text").map((part) => "text" in part ? part.text : "").join("\n\n"));
|
|
125
126
|
setRole(message.role);
|
|
126
127
|
setAttachments(message.attachments ?? []);
|
|
127
128
|
}
|
|
128
129
|
});
|
|
129
|
-
|
|
130
|
+
useEffect(() => {
|
|
130
131
|
if (isEditing) updateFromMessage();
|
|
131
132
|
}, [isEditing]);
|
|
132
|
-
const attachmentClients =
|
|
133
|
+
const attachmentClients = useClientLookup(() => attachments.map((attachment, idx) => withKey(attachment.id, AttachmentResource({
|
|
133
134
|
attachment,
|
|
134
135
|
onRemove: () => {
|
|
135
136
|
setAttachments(attachments.filter((_, i) => i !== idx));
|
|
136
137
|
}
|
|
137
138
|
}))), [attachments]);
|
|
138
139
|
const queueItems = queue?.items ?? EMPTY_QUEUE_ITEMS;
|
|
139
|
-
const queueItemClients =
|
|
140
|
+
const queueItemClients = useClientLookup(() => queueItems.map((item) => withKey(item.id, QueueItemClient({
|
|
140
141
|
item,
|
|
141
142
|
onSteer: () => queue?.steer(item.id),
|
|
142
143
|
onRemove: () => queue?.remove(item.id)
|
|
143
144
|
}))), [queueItems]);
|
|
144
|
-
const state =
|
|
145
|
+
const state = useMemo(() => {
|
|
145
146
|
const isEmpty = !text.trim() && !attachments.length;
|
|
146
147
|
return {
|
|
147
148
|
text,
|
|
@@ -249,7 +250,7 @@ const ComposerClientResource = resource(({ type, isEditing, canCancel, isSendDis
|
|
|
249
250
|
}
|
|
250
251
|
};
|
|
251
252
|
});
|
|
252
|
-
const ExternalThread = resource(({ messages, isRunning = false, isSendDisabled = false, onNew, onEdit, onReload, onStartRun, onCancel, queue })
|
|
253
|
+
const ExternalThread = resource(function ExternalThread({ messages, isRunning = false, isSendDisabled = false, onNew, onEdit, onReload, onStartRun, onCancel, queue }) {
|
|
253
254
|
const handleReload = (messageId) => {
|
|
254
255
|
const messageIndex = messages.findIndex((m) => m.id === messageId);
|
|
255
256
|
if (messageIndex === -1) return;
|
|
@@ -257,7 +258,7 @@ const ExternalThread = resource(({ messages, isRunning = false, isSendDisabled =
|
|
|
257
258
|
queue?.clear("reload");
|
|
258
259
|
onReload?.(parentId);
|
|
259
260
|
};
|
|
260
|
-
const messageClients =
|
|
261
|
+
const messageClients = useClientLookup(() => messages.map((msg, index) => {
|
|
261
262
|
const props = {
|
|
262
263
|
message: msg,
|
|
263
264
|
index,
|
|
@@ -278,7 +279,7 @@ const ExternalThread = resource(({ messages, isRunning = false, isSendDisabled =
|
|
|
278
279
|
const handleSendNew = (message) => {
|
|
279
280
|
onNew?.(message);
|
|
280
281
|
};
|
|
281
|
-
const composerClient =
|
|
282
|
+
const composerClient = useClientResource(ComposerClientResource({
|
|
282
283
|
type: "thread",
|
|
283
284
|
isEditing: true,
|
|
284
285
|
canCancel: isRunning,
|
|
@@ -288,7 +289,7 @@ const ExternalThread = resource(({ messages, isRunning = false, isSendDisabled =
|
|
|
288
289
|
queue
|
|
289
290
|
}));
|
|
290
291
|
const hasQueue = !!queue;
|
|
291
|
-
const state =
|
|
292
|
+
const state = useMemo(() => {
|
|
292
293
|
const messageStates = messageClients.state.map((s, idx, arr) => ({
|
|
293
294
|
...s,
|
|
294
295
|
isLast: idx === arr.length - 1
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ExternalThread.js","names":[],"sources":["../../src/client/ExternalThread.ts"],"sourcesContent":["import {\n resource,\n tapState,\n tapMemo,\n tapEffect,\n tapEffectEvent,\n} from \"@assistant-ui/tap\";\nimport {\n type ClientElement,\n type ClientOutput,\n tapClientLookup,\n attachTransformScopes,\n tapClientResource,\n Derived,\n} from \"@assistant-ui/store\";\nimport { withKey } from \"@assistant-ui/tap\";\nimport type {\n AppendMessage,\n Attachment,\n CreateAttachment,\n ThreadAssistantMessagePart,\n ThreadUserMessagePart,\n ThreadMessage,\n} from \"@assistant-ui/core\";\nimport type { QueueItemState } from \"@assistant-ui/core/store\";\nimport type { ComposerSendOptions } from \"@assistant-ui/core/store\";\nimport { ModelContext, Suggestions } from \"@assistant-ui/core/store\";\nimport { Tools, DataRenderers } from \"@assistant-ui/core/react\";\nimport { SingleThreadList } from \"./SingleThreadList\";\n\nconst EMPTY_QUEUE_ITEMS: readonly QueueItemState[] = [];\n\nexport type ExternalThreadMessage = ThreadMessage & {\n id: string;\n};\n\nexport type ExternalThreadQueueAdapter = {\n /** The current queue items. */\n items: readonly QueueItemState[];\n /** Called when a message is submitted via the composer. Receives the steer preference. */\n enqueue: (message: AppendMessage, opts: { steer: boolean }) => void;\n /** Called to promote an existing queue item (cancel current run, run this immediately). */\n steer: (queueItemId: string) => void;\n /** Called to remove an item from the queue. */\n remove: (queueItemId: string) => void;\n /** Called to clear all pending queue items, with the reason for clearing. */\n clear: (reason: \"edit\" | \"reload\" | \"cancel-run\") => void;\n};\n\nexport type ExternalThreadProps = {\n messages: readonly ExternalThreadMessage[];\n isRunning?: boolean;\n /**\n * Whether sending new messages is currently disabled. When `true`, the\n * thread composer's input remains usable but `send()` is a no-op and\n * `composer.canSend` is `false`. Edit composers (saving message edits)\n * intentionally ignore this flag.\n */\n isSendDisabled?: boolean;\n /**\n * Callback for new messages (non-queue runtimes).\n * @note Unused when `queue` is provided — new messages are routed through `queue.enqueue` instead.\n */\n onNew?: (message: AppendMessage) => void;\n onEdit?: (message: AppendMessage) => void;\n onReload?: (parentId: string | null) => void;\n onStartRun?: () => void;\n onCancel?: () => void;\n /** Queue adapter for runtimes that support message queuing and steering. */\n queue?: ExternalThreadQueueAdapter;\n};\n\ntype MessageClientProps = {\n message: ExternalThreadMessage;\n index: number;\n onEdit?: (message: AppendMessage) => void;\n onReload?: () => void;\n queue?: ExternalThreadQueueAdapter | undefined;\n};\n\n// Message Client - minimal implementation\nconst MessageClient = resource(\n ({\n message,\n index,\n onEdit,\n onReload,\n queue,\n }: MessageClientProps): ClientOutput<\"message\"> => {\n const [isCopied, setIsCopied] = tapState(false);\n const [isHovering, setIsHovering] = tapState(false);\n const [isEditing, setIsEditing] = tapState(false);\n\n const partClients = tapClientLookup(\n () =>\n message.content.map((part, idx) =>\n withKey(idx, PartResource({ part })),\n ),\n [message.content],\n );\n\n const attachmentClients = tapClientLookup(\n () =>\n (message.attachments ?? []).map((attachment) =>\n withKey(\n attachment.id,\n AttachmentResource({\n attachment,\n onRemove: () => {},\n }),\n ),\n ),\n [message.attachments],\n );\n\n const handleBeginEdit = () => {\n setIsEditing(true);\n };\n\n const handleCancelEdit = () => {\n setIsEditing(false);\n };\n\n const handleSendEdit = (msg: AppendMessage) => {\n queue?.clear(\"edit\");\n onEdit?.({\n ...msg,\n parentId: message.id,\n sourceId: message.id,\n });\n setIsEditing(false);\n };\n\n const composerClient = tapClientResource(\n ComposerClientResource({\n type: \"edit\",\n isEditing,\n canCancel: true,\n onCancel: handleCancelEdit,\n onBeginEdit: handleBeginEdit,\n onSend: handleSendEdit,\n message,\n queue,\n }),\n );\n\n const state = tapMemo(() => {\n return {\n ...message,\n attachments: message.attachments ?? [],\n parentId: null,\n isLast: false, // Will be set by thread\n branchNumber: 1,\n branchCount: 1,\n speech: undefined,\n parts: partClients.state,\n isCopied,\n isHovering,\n index,\n composer: composerClient.state,\n };\n }, [\n message,\n isCopied,\n isHovering,\n index,\n composerClient.state,\n partClients.state,\n ]);\n\n return {\n getState: () => state,\n composer: () => composerClient.methods,\n reload: () => {\n onReload?.();\n },\n speak: () => {},\n stopSpeaking: () => {},\n submitFeedback: () => {},\n switchToBranch: () => {},\n getCopyText: () =>\n message.content.map((c) => (\"text\" in c ? c.text : \"\")).join(\"\"),\n part: (selector) => {\n if (\"index\" in selector) {\n return partClients.get(selector);\n }\n const partIndex = state.parts.findIndex(\n (p) => p.type === \"tool-call\" && p.toolCallId === selector.toolCallId,\n );\n return partClients.get({ index: partIndex });\n },\n attachment: (selector) => {\n if (\"id\" in selector) {\n return attachmentClients.get({ key: selector.id });\n }\n return attachmentClients.get(selector);\n },\n setIsCopied,\n setIsHovering,\n };\n },\n);\n\ntype PartResourceProps = {\n part: ThreadAssistantMessagePart | ThreadUserMessagePart;\n};\n\n// Part Client - minimal implementation\nconst PartResource = resource(\n ({ part }: PartResourceProps): ClientOutput<\"part\"> => {\n const state = tapMemo(\n () => ({\n ...part,\n status: { type: \"complete\" as const },\n }),\n [part],\n );\n\n return {\n getState: () => state,\n addToolResult: () => {},\n resumeToolCall: () => {},\n respondToToolApproval: () => {},\n };\n },\n);\n\ntype AttachmentResourceProps = {\n attachment: Attachment;\n onRemove?: () => void;\n};\n\n// Attachment Client - minimal implementation\nconst AttachmentResource = resource(\n ({\n attachment,\n onRemove,\n }: AttachmentResourceProps): ClientOutput<\"attachment\"> => {\n return {\n getState: () => attachment,\n remove: async () => {\n onRemove?.();\n },\n };\n },\n);\n\ntype ComposerClientResourceProps = {\n type: \"thread\" | \"edit\";\n isEditing: boolean;\n canCancel: boolean;\n isSendDisabled?: boolean;\n onCancel: () => void;\n onBeginEdit?: () => void;\n onSend?: (message: AppendMessage) => void;\n message?: ExternalThreadMessage;\n queue?: ExternalThreadQueueAdapter | undefined;\n};\n\nconst QueueItemClient = resource(\n ({\n item,\n onSteer,\n onRemove,\n }: {\n item: QueueItemState;\n onSteer: () => void;\n onRemove: () => void;\n }): ClientOutput<\"queueItem\"> => {\n return {\n getState: () => item,\n steer: onSteer,\n remove: onRemove,\n };\n },\n);\n\n// Composer Client - minimal implementation\nconst ComposerClientResource = resource(\n ({\n type,\n isEditing,\n canCancel,\n isSendDisabled = false,\n onCancel,\n onBeginEdit,\n onSend,\n message,\n queue,\n }: ComposerClientResourceProps): ClientOutput<\"composer\"> => {\n const [text, setText] = tapState(\"\");\n const [role, setRole] = tapState<\"user\" | \"assistant\" | \"system\">(\"user\");\n const [runConfig, setRunConfig] = tapState<Record<string, unknown>>({});\n const [attachments, setAttachments] = tapState<readonly Attachment[]>([]);\n const [quote, setQuote] = tapState<\n { readonly text: string; readonly messageId: string } | undefined\n >(undefined);\n\n // Update composer values when editing begins\n const updateFromMessage = tapEffectEvent(() => {\n if (message) {\n // Extract text from message content (text parts only)\n const textParts = message.content.filter(\n (part) => part.type === \"text\",\n );\n const messageText = textParts\n .map((part) => (\"text\" in part ? part.text : \"\"))\n .join(\"\\n\\n\");\n\n setText(messageText);\n setRole(message.role);\n setAttachments(message.attachments ?? []);\n }\n });\n\n tapEffect(() => {\n if (isEditing) {\n updateFromMessage();\n }\n }, [isEditing]);\n\n const attachmentClients = tapClientLookup(\n () =>\n attachments.map((attachment, idx) =>\n withKey(\n attachment.id,\n AttachmentResource({\n attachment,\n onRemove: () => {\n setAttachments(attachments.filter((_, i) => i !== idx));\n },\n }),\n ),\n ),\n [attachments],\n );\n\n const queueItems = queue?.items ?? EMPTY_QUEUE_ITEMS;\n const queueItemClients = tapClientLookup(\n () =>\n queueItems.map((item) =>\n withKey(\n item.id,\n QueueItemClient({\n item,\n onSteer: () => queue?.steer(item.id),\n onRemove: () => queue?.remove(item.id),\n }),\n ),\n ),\n [queueItems],\n );\n\n const state = tapMemo(() => {\n const isEmpty = !text.trim() && !attachments.length;\n return {\n text,\n role,\n attachments: attachmentClients.state,\n runConfig,\n isEditing,\n canCancel,\n canSend: isEditing && !isEmpty && !isSendDisabled,\n attachmentAccept: \"*\",\n isEmpty,\n type,\n dictation: undefined,\n quote,\n queue: queueItems,\n };\n }, [\n text,\n role,\n attachmentClients.state,\n runConfig,\n isEditing,\n canCancel,\n isSendDisabled,\n type,\n attachments.length,\n quote,\n queueItems,\n ]);\n\n return {\n getState: () => state,\n setText,\n setRole,\n setRunConfig,\n addAttachment: async (fileOrAttachment: File | CreateAttachment) => {\n if (fileOrAttachment instanceof File) {\n const newAttachment: Attachment = {\n id: Math.random().toString(36).substring(7),\n type: \"file\",\n name: fileOrAttachment.name,\n contentType: fileOrAttachment.type,\n file: fileOrAttachment,\n status: { type: \"complete\" },\n content: [],\n };\n setAttachments([...attachments, newAttachment]);\n } else {\n const newAttachment: Attachment = {\n id: fileOrAttachment.id ?? Math.random().toString(36).substring(7),\n type: fileOrAttachment.type ?? \"document\",\n name: fileOrAttachment.name,\n contentType: fileOrAttachment.contentType,\n content: fileOrAttachment.content,\n status: { type: \"complete\" },\n };\n setAttachments([...attachments, newAttachment]);\n }\n },\n clearAttachments: async () => {\n setAttachments([]);\n },\n attachment: (selector) => {\n if (\"id\" in selector) {\n return attachmentClients.get({ key: selector.id });\n }\n return attachmentClients.get(selector);\n },\n reset: async () => {\n setText(\"\");\n setRole(\"user\");\n setRunConfig({});\n setAttachments([]);\n setQuote(undefined);\n },\n send: (opts?: ComposerSendOptions) => {\n if (!state.canSend) return;\n\n const currentQuote = quote;\n const composedMessage: AppendMessage = {\n role,\n content: text ? [{ type: \"text\" as const, text }] : [],\n attachments: attachments as any,\n createdAt: new Date(),\n parentId: null,\n sourceId: null,\n runConfig,\n startRun: opts?.startRun,\n metadata: {\n custom: { ...(currentQuote ? { quote: currentQuote } : {}) },\n },\n };\n if (queue) {\n queue.enqueue(composedMessage, { steer: opts?.steer ?? false });\n } else {\n onSend?.(composedMessage);\n }\n setText(\"\");\n setAttachments([]);\n setQuote(undefined);\n },\n cancel: onCancel,\n beginEdit: () => {\n onBeginEdit?.();\n },\n startDictation: () => {},\n stopDictation: () => {},\n setQuote,\n queueItem: (selector: { index: number }) => {\n return queueItemClients.get(selector);\n },\n };\n },\n);\n\n// External Thread Client\nexport const ExternalThread = resource(\n ({\n messages,\n isRunning = false,\n isSendDisabled = false,\n onNew,\n onEdit,\n onReload,\n onStartRun,\n onCancel,\n queue,\n }: ExternalThreadProps): ClientOutput<\"thread\"> => {\n const handleReload = (messageId: string) => {\n const messageIndex = messages.findIndex((m) => m.id === messageId);\n if (messageIndex === -1) return;\n\n const parentId = messageIndex > 0 ? messages[messageIndex - 1]!.id : null;\n queue?.clear(\"reload\");\n onReload?.(parentId);\n };\n\n const messageClients = tapClientLookup(\n () =>\n messages.map((msg, index) => {\n const props: MessageClientProps = {\n message: msg,\n index,\n onReload: () => handleReload(msg.id),\n queue,\n };\n if (onEdit) props.onEdit = onEdit;\n return withKey(msg.id, MessageClient(props));\n }),\n [messages, onEdit, queue],\n );\n\n const handleCancelRun = () => {\n queue?.clear(\"cancel-run\");\n onCancel?.();\n };\n\n const handleSendNew = (message: AppendMessage) => {\n onNew?.(message);\n };\n\n const composerClient = tapClientResource(\n ComposerClientResource({\n type: \"thread\",\n isEditing: true,\n canCancel: isRunning,\n isSendDisabled,\n onCancel: handleCancelRun,\n onSend: handleSendNew,\n queue,\n }),\n );\n\n const hasQueue = !!queue;\n const state = tapMemo(() => {\n const messageStates = messageClients.state.map((s, idx, arr) => ({\n ...s,\n isLast: idx === arr.length - 1,\n }));\n\n return {\n isEmpty: messages.length === 0,\n isDisabled: false,\n isLoading: false,\n isRunning,\n capabilities: {\n edit: false,\n reload: false,\n cancel: isRunning,\n speech: false,\n attachments: false,\n feedback: false,\n voice: false,\n switchToBranch: false,\n switchBranchDuringRun: false,\n unstable_copy: false,\n dictation: false,\n queue: hasQueue,\n },\n messages: messageStates,\n state: {},\n suggestions: [],\n extras: undefined,\n speech: undefined,\n voice: undefined,\n composer: composerClient.state,\n };\n }, [\n messages,\n isRunning,\n hasQueue,\n messageClients.state,\n composerClient.state,\n ]);\n\n return {\n getState: () => state,\n composer: () => composerClient.methods,\n append: (message) => {\n const appendMessage: AppendMessage =\n typeof message === \"string\"\n ? {\n createdAt: new Date(),\n parentId: messages.at(-1)?.id ?? null,\n sourceId: null,\n runConfig: {},\n role: \"user\",\n content: [{ type: \"text\", text: message }],\n attachments: [],\n metadata: { custom: {} },\n }\n : {\n createdAt: message.createdAt ?? new Date(),\n parentId: message.parentId ?? messages.at(-1)?.id ?? null,\n sourceId: message.sourceId ?? null,\n role: message.role ?? \"user\",\n content: message.content,\n attachments: message.attachments ?? [],\n metadata: message.metadata ?? { custom: {} },\n runConfig: message.runConfig ?? {},\n startRun: message.startRun,\n };\n if (queue) {\n queue.enqueue(appendMessage, { steer: false });\n } else {\n onNew?.(appendMessage);\n }\n },\n startRun: () => {\n onStartRun?.();\n },\n resumeRun: () => {},\n cancelRun: handleCancelRun,\n getModelContext: () => ({ tools: {}, config: {} }),\n export: () => ({ messages: [] }),\n import: () => {},\n reset: () => {},\n message: (selector) => {\n if (\"id\" in selector) {\n return messageClients.get({ key: selector.id });\n }\n return messageClients.get(selector);\n },\n stopSpeaking: () => {},\n connectVoice: () => {},\n disconnectVoice: () => {},\n getVoiceVolume: () => 0,\n subscribeVoiceVolume: () => () => {},\n muteVoice: () => {},\n unmuteVoice: () => {},\n };\n },\n);\n\nattachTransformScopes(ExternalThread, (scopes, parent) => {\n if (!scopes.threads && parent.threads.source === null) {\n const threadElement = scopes.thread as ClientElement<\"thread\">;\n scopes.threads = SingleThreadList({ thread: threadElement });\n scopes.thread = Derived({\n source: \"threads\",\n query: { type: \"main\" },\n get: (aui) => aui.threads().thread(\"main\"),\n });\n }\n\n if (!scopes.threadListItem && parent.threadListItem.source === null) {\n scopes.threadListItem = Derived({\n source: \"threads\",\n query: { type: \"main\" },\n get: (aui) => aui.threads().item(\"main\"),\n });\n }\n\n scopes.composer ??= Derived({\n source: \"thread\",\n query: {},\n get: (aui) => aui.thread().composer(),\n });\n\n if (!scopes.modelContext && parent.modelContext.source === null) {\n scopes.modelContext = ModelContext();\n }\n if (!scopes.tools && parent.tools.source === null) {\n scopes.tools = Tools({});\n }\n if (!scopes.dataRenderers && parent.dataRenderers.source === null) {\n scopes.dataRenderers = DataRenderers();\n }\n if (!scopes.suggestions && parent.suggestions.source === null) {\n scopes.suggestions = Suggestions();\n }\n});\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"ExternalThread.js","names":[],"sources":["../../src/client/ExternalThread.ts"],"sourcesContent":["import { useState, useMemo, useEffect, useEffectEvent } from \"react\";\nimport { resource, withKey } from \"@assistant-ui/tap\";\nimport {\n type ClientElement,\n type ClientOutput,\n useClientLookup,\n attachTransformScopes,\n useClientResource,\n Derived,\n} from \"@assistant-ui/store\";\n\nimport type {\n AppendMessage,\n Attachment,\n CreateAttachment,\n ThreadAssistantMessagePart,\n ThreadUserMessagePart,\n ThreadMessage,\n ExternalThreadQueueAdapter,\n} from \"@assistant-ui/core\";\nimport type { QueueItemState } from \"@assistant-ui/core/store\";\nimport type { ComposerSendOptions } from \"@assistant-ui/core/store\";\nimport { ModelContext, Suggestions } from \"@assistant-ui/core/store\";\nimport { Tools, DataRenderers } from \"@assistant-ui/core/react\";\nimport { SingleThreadList } from \"./SingleThreadList\";\n\nconst EMPTY_QUEUE_ITEMS: readonly QueueItemState[] = [];\n\nexport type ExternalThreadMessage = ThreadMessage & {\n id: string;\n};\n\nexport type ExternalThreadProps = {\n messages: readonly ExternalThreadMessage[];\n isRunning?: boolean;\n /**\n * Whether sending new messages is currently disabled. When `true`, the\n * thread composer's input remains usable but `send()` is a no-op and\n * `composer.canSend` is `false`. Edit composers (saving message edits)\n * intentionally ignore this flag.\n */\n isSendDisabled?: boolean;\n /**\n * Callback for new messages (non-queue runtimes).\n * @note Unused when `queue` is provided — new messages are routed through `queue.enqueue` instead.\n */\n onNew?: (message: AppendMessage) => void;\n onEdit?: (message: AppendMessage) => void;\n onReload?: (parentId: string | null) => void;\n onStartRun?: () => void;\n onCancel?: () => void;\n /** Queue adapter for runtimes that support message queuing and steering. */\n queue?: ExternalThreadQueueAdapter;\n};\n\ntype MessageClientProps = {\n message: ExternalThreadMessage;\n index: number;\n onEdit?: (message: AppendMessage) => void;\n onReload?: () => void;\n queue?: ExternalThreadQueueAdapter | undefined;\n};\n\n// Message Client - minimal implementation\nconst MessageClient = resource(function MessageClient({\n message,\n index,\n onEdit,\n onReload,\n queue,\n}: MessageClientProps): ClientOutput<\"message\"> {\n const [isCopied, setIsCopied] = useState(false);\n const [isHovering, setIsHovering] = useState(false);\n const [isEditing, setIsEditing] = useState(false);\n\n const partClients = useClientLookup(\n () =>\n message.content.map((part, idx) => withKey(idx, PartResource({ part }))),\n [message.content],\n );\n\n const attachmentClients = useClientLookup(\n () =>\n (message.attachments ?? []).map((attachment) =>\n withKey(\n attachment.id,\n AttachmentResource({\n attachment,\n onRemove: () => {},\n }),\n ),\n ),\n [message.attachments],\n );\n\n const handleBeginEdit = () => {\n setIsEditing(true);\n };\n\n const handleCancelEdit = () => {\n setIsEditing(false);\n };\n\n const handleSendEdit = (msg: AppendMessage) => {\n queue?.clear(\"edit\");\n onEdit?.({\n ...msg,\n parentId: message.id,\n sourceId: message.id,\n });\n setIsEditing(false);\n };\n\n const composerClient = useClientResource(\n ComposerClientResource({\n type: \"edit\",\n isEditing,\n canCancel: true,\n onCancel: handleCancelEdit,\n onBeginEdit: handleBeginEdit,\n onSend: handleSendEdit,\n message,\n queue,\n }),\n );\n\n const state = useMemo(() => {\n return {\n ...message,\n attachments: message.attachments ?? [],\n parentId: null,\n isLast: false, // Will be set by thread\n branchNumber: 1,\n branchCount: 1,\n speech: undefined,\n parts: partClients.state,\n isCopied,\n isHovering,\n index,\n composer: composerClient.state,\n };\n }, [\n message,\n isCopied,\n isHovering,\n index,\n composerClient.state,\n partClients.state,\n ]);\n\n return {\n getState: () => state,\n composer: () => composerClient.methods,\n reload: () => {\n onReload?.();\n },\n speak: () => {},\n stopSpeaking: () => {},\n submitFeedback: () => {},\n switchToBranch: () => {},\n getCopyText: () =>\n message.content.map((c) => (\"text\" in c ? c.text : \"\")).join(\"\"),\n part: (selector) => {\n if (\"index\" in selector) {\n return partClients.get(selector);\n }\n const partIndex = state.parts.findIndex(\n (p) => p.type === \"tool-call\" && p.toolCallId === selector.toolCallId,\n );\n return partClients.get({ index: partIndex });\n },\n attachment: (selector) => {\n if (\"id\" in selector) {\n return attachmentClients.get({ key: selector.id });\n }\n return attachmentClients.get(selector);\n },\n setIsCopied,\n setIsHovering,\n };\n});\n\ntype PartResourceProps = {\n part: ThreadAssistantMessagePart | ThreadUserMessagePart;\n};\n\n// Part Client - minimal implementation\nconst PartResource = resource(function PartResource({\n part,\n}: PartResourceProps): ClientOutput<\"part\"> {\n const state = useMemo(\n () => ({\n ...part,\n status: { type: \"complete\" as const },\n }),\n [part],\n );\n\n return {\n getState: () => state,\n addToolResult: () => {},\n resumeToolCall: () => {},\n respondToToolApproval: () => {},\n };\n});\n\ntype AttachmentResourceProps = {\n attachment: Attachment;\n onRemove?: () => void;\n};\n\n// Attachment Client - minimal implementation\nconst AttachmentResource = resource(function AttachmentResource({\n attachment,\n onRemove,\n}: AttachmentResourceProps): ClientOutput<\"attachment\"> {\n return {\n getState: () => attachment,\n remove: async () => {\n onRemove?.();\n },\n };\n});\n\ntype ComposerClientResourceProps = {\n type: \"thread\" | \"edit\";\n isEditing: boolean;\n canCancel: boolean;\n isSendDisabled?: boolean;\n onCancel: () => void;\n onBeginEdit?: () => void;\n onSend?: (message: AppendMessage) => void;\n message?: ExternalThreadMessage;\n queue?: ExternalThreadQueueAdapter | undefined;\n};\n\nconst QueueItemClient = resource(function QueueItemClient({\n item,\n onSteer,\n onRemove,\n}: {\n item: QueueItemState;\n onSteer: () => void;\n onRemove: () => void;\n}): ClientOutput<\"queueItem\"> {\n return {\n getState: () => item,\n steer: onSteer,\n remove: onRemove,\n };\n});\n\n// Composer Client - minimal implementation\nconst ComposerClientResource = resource(function ComposerClientResource({\n type,\n isEditing,\n canCancel,\n isSendDisabled = false,\n onCancel,\n onBeginEdit,\n onSend,\n message,\n queue,\n}: ComposerClientResourceProps): ClientOutput<\"composer\"> {\n const [text, setText] = useState(\"\");\n const [role, setRole] = useState<\"user\" | \"assistant\" | \"system\">(\"user\");\n const [runConfig, setRunConfig] = useState<Record<string, unknown>>({});\n const [attachments, setAttachments] = useState<readonly Attachment[]>([]);\n const [quote, setQuote] = useState<\n { readonly text: string; readonly messageId: string } | undefined\n >(undefined);\n\n // Update composer values when editing begins\n const updateFromMessage = useEffectEvent(() => {\n if (message) {\n // Extract text from message content (text parts only)\n const textParts = message.content.filter((part) => part.type === \"text\");\n const messageText = textParts\n .map((part) => (\"text\" in part ? part.text : \"\"))\n .join(\"\\n\\n\");\n\n setText(messageText);\n setRole(message.role);\n setAttachments(message.attachments ?? []);\n }\n });\n\n useEffect(() => {\n if (isEditing) {\n updateFromMessage();\n }\n }, [isEditing]);\n\n const attachmentClients = useClientLookup(\n () =>\n attachments.map((attachment, idx) =>\n withKey(\n attachment.id,\n AttachmentResource({\n attachment,\n onRemove: () => {\n setAttachments(attachments.filter((_, i) => i !== idx));\n },\n }),\n ),\n ),\n [attachments],\n );\n\n const queueItems = queue?.items ?? EMPTY_QUEUE_ITEMS;\n const queueItemClients = useClientLookup(\n () =>\n queueItems.map((item) =>\n withKey(\n item.id,\n QueueItemClient({\n item,\n onSteer: () => queue?.steer(item.id),\n onRemove: () => queue?.remove(item.id),\n }),\n ),\n ),\n [queueItems],\n );\n\n const state = useMemo(() => {\n const isEmpty = !text.trim() && !attachments.length;\n return {\n text,\n role,\n attachments: attachmentClients.state,\n runConfig,\n isEditing,\n canCancel,\n canSend: isEditing && !isEmpty && !isSendDisabled,\n attachmentAccept: \"*\",\n isEmpty,\n type,\n dictation: undefined,\n quote,\n queue: queueItems,\n };\n }, [\n text,\n role,\n attachmentClients.state,\n runConfig,\n isEditing,\n canCancel,\n isSendDisabled,\n type,\n attachments.length,\n quote,\n queueItems,\n ]);\n\n return {\n getState: () => state,\n setText,\n setRole,\n setRunConfig,\n addAttachment: async (fileOrAttachment: File | CreateAttachment) => {\n if (fileOrAttachment instanceof File) {\n const newAttachment: Attachment = {\n id: Math.random().toString(36).substring(7),\n type: \"file\",\n name: fileOrAttachment.name,\n contentType: fileOrAttachment.type,\n file: fileOrAttachment,\n status: { type: \"complete\" },\n content: [],\n };\n setAttachments([...attachments, newAttachment]);\n } else {\n const newAttachment: Attachment = {\n id: fileOrAttachment.id ?? Math.random().toString(36).substring(7),\n type: fileOrAttachment.type ?? \"document\",\n name: fileOrAttachment.name,\n contentType: fileOrAttachment.contentType,\n content: fileOrAttachment.content,\n status: { type: \"complete\" },\n };\n setAttachments([...attachments, newAttachment]);\n }\n },\n clearAttachments: async () => {\n setAttachments([]);\n },\n attachment: (selector) => {\n if (\"id\" in selector) {\n return attachmentClients.get({ key: selector.id });\n }\n return attachmentClients.get(selector);\n },\n reset: async () => {\n setText(\"\");\n setRole(\"user\");\n setRunConfig({});\n setAttachments([]);\n setQuote(undefined);\n },\n send: (opts?: ComposerSendOptions) => {\n if (!state.canSend) return;\n\n const currentQuote = quote;\n const composedMessage: AppendMessage = {\n role,\n content: text ? [{ type: \"text\" as const, text }] : [],\n attachments: attachments as any,\n createdAt: new Date(),\n parentId: null,\n sourceId: null,\n runConfig,\n startRun: opts?.startRun,\n metadata: {\n custom: { ...(currentQuote ? { quote: currentQuote } : {}) },\n },\n };\n if (queue) {\n queue.enqueue(composedMessage, { steer: opts?.steer ?? false });\n } else {\n onSend?.(composedMessage);\n }\n setText(\"\");\n setAttachments([]);\n setQuote(undefined);\n },\n cancel: onCancel,\n beginEdit: () => {\n onBeginEdit?.();\n },\n startDictation: () => {},\n stopDictation: () => {},\n setQuote,\n queueItem: (selector: { index: number }) => {\n return queueItemClients.get(selector);\n },\n };\n});\n\n// External Thread Client\nexport const ExternalThread = resource(function ExternalThread({\n messages,\n isRunning = false,\n isSendDisabled = false,\n onNew,\n onEdit,\n onReload,\n onStartRun,\n onCancel,\n queue,\n}: ExternalThreadProps): ClientOutput<\"thread\"> {\n const handleReload = (messageId: string) => {\n const messageIndex = messages.findIndex((m) => m.id === messageId);\n if (messageIndex === -1) return;\n\n const parentId = messageIndex > 0 ? messages[messageIndex - 1]!.id : null;\n queue?.clear(\"reload\");\n onReload?.(parentId);\n };\n\n const messageClients = useClientLookup(\n () =>\n messages.map((msg, index) => {\n const props: MessageClientProps = {\n message: msg,\n index,\n onReload: () => handleReload(msg.id),\n queue,\n };\n if (onEdit) props.onEdit = onEdit;\n return withKey(msg.id, MessageClient(props));\n }),\n [messages, onEdit, queue],\n );\n\n const handleCancelRun = () => {\n queue?.clear(\"cancel-run\");\n onCancel?.();\n };\n\n const handleSendNew = (message: AppendMessage) => {\n onNew?.(message);\n };\n\n const composerClient = useClientResource(\n ComposerClientResource({\n type: \"thread\",\n isEditing: true,\n canCancel: isRunning,\n isSendDisabled,\n onCancel: handleCancelRun,\n onSend: handleSendNew,\n queue,\n }),\n );\n\n const hasQueue = !!queue;\n const state = useMemo(() => {\n const messageStates = messageClients.state.map((s, idx, arr) => ({\n ...s,\n isLast: idx === arr.length - 1,\n }));\n\n return {\n isEmpty: messages.length === 0,\n isDisabled: false,\n isLoading: false,\n isRunning,\n capabilities: {\n edit: false,\n reload: false,\n cancel: isRunning,\n speech: false,\n attachments: false,\n feedback: false,\n voice: false,\n switchToBranch: false,\n switchBranchDuringRun: false,\n unstable_copy: false,\n dictation: false,\n queue: hasQueue,\n },\n messages: messageStates,\n state: {},\n suggestions: [],\n extras: undefined,\n speech: undefined,\n voice: undefined,\n composer: composerClient.state,\n };\n }, [\n messages,\n isRunning,\n hasQueue,\n messageClients.state,\n composerClient.state,\n ]);\n\n return {\n getState: () => state,\n composer: () => composerClient.methods,\n append: (message) => {\n const appendMessage: AppendMessage =\n typeof message === \"string\"\n ? {\n createdAt: new Date(),\n parentId: messages.at(-1)?.id ?? null,\n sourceId: null,\n runConfig: {},\n role: \"user\",\n content: [{ type: \"text\", text: message }],\n attachments: [],\n metadata: { custom: {} },\n }\n : {\n createdAt: message.createdAt ?? new Date(),\n parentId: message.parentId ?? messages.at(-1)?.id ?? null,\n sourceId: message.sourceId ?? null,\n role: message.role ?? \"user\",\n content: message.content,\n attachments: message.attachments ?? [],\n metadata: message.metadata ?? { custom: {} },\n runConfig: message.runConfig ?? {},\n startRun: message.startRun,\n };\n if (queue) {\n queue.enqueue(appendMessage, { steer: false });\n } else {\n onNew?.(appendMessage);\n }\n },\n startRun: () => {\n onStartRun?.();\n },\n resumeRun: () => {},\n cancelRun: handleCancelRun,\n getModelContext: () => ({ tools: {}, config: {} }),\n export: () => ({ messages: [] }),\n import: () => {},\n reset: () => {},\n message: (selector) => {\n if (\"id\" in selector) {\n return messageClients.get({ key: selector.id });\n }\n return messageClients.get(selector);\n },\n stopSpeaking: () => {},\n connectVoice: () => {},\n disconnectVoice: () => {},\n getVoiceVolume: () => 0,\n subscribeVoiceVolume: () => () => {},\n muteVoice: () => {},\n unmuteVoice: () => {},\n };\n});\n\nattachTransformScopes(ExternalThread, (scopes, parent) => {\n if (!scopes.threads && parent.threads.source === null) {\n const threadElement = scopes.thread as ClientElement<\"thread\">;\n scopes.threads = SingleThreadList({ thread: threadElement });\n scopes.thread = Derived({\n source: \"threads\",\n query: { type: \"main\" },\n get: (aui) => aui.threads().thread(\"main\"),\n });\n }\n\n if (!scopes.threadListItem && parent.threadListItem.source === null) {\n scopes.threadListItem = Derived({\n source: \"threads\",\n query: { type: \"main\" },\n get: (aui) => aui.threads().item(\"main\"),\n });\n }\n\n scopes.composer ??= Derived({\n source: \"thread\",\n query: {},\n get: (aui) => aui.thread().composer(),\n });\n\n if (!scopes.modelContext && parent.modelContext.source === null) {\n scopes.modelContext = ModelContext();\n }\n if (!scopes.tools && parent.tools.source === null) {\n scopes.tools = Tools({});\n }\n if (!scopes.dataRenderers && parent.dataRenderers.source === null) {\n scopes.dataRenderers = DataRenderers();\n }\n if (!scopes.suggestions && parent.suggestions.source === null) {\n scopes.suggestions = Suggestions();\n }\n});\n"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"InMemoryThreadList.d.ts","names":[],"sources":["../../src/client/InMemoryThreadList.ts"],"mappings":";;;;
|
|
1
|
+
{"version":3,"file":"InMemoryThreadList.d.ts","names":[],"sources":["../../src/client/InMemoryThreadList.ts"],"mappings":";;;;KAeY,uBAAA;EACV,MAAA,GAAS,QAAA,aAAqB,eAAe,CAAC,YAAA;EAC9C,gBAAA,IAAoB,QAAA;EACpB,mBAAA;AAAA;AAAA,cAgDW,kBAAA,GAAkB,KAAA,EAAA,uBAAA,KAAA,eAAA,CAAA,YAAA,aAAA,uBAAA"}
|
|
@@ -1,12 +1,13 @@
|
|
|
1
|
-
import { Derived, attachTransformScopes,
|
|
1
|
+
import { Derived, attachTransformScopes, useClientLookup, useClientResource } from "@assistant-ui/store";
|
|
2
2
|
import { DataRenderers, Tools } from "@assistant-ui/core/react";
|
|
3
|
+
import { useMemo, useState } from "@assistant-ui/tap/react-shim";
|
|
3
4
|
import { ModelContext, Suggestions } from "@assistant-ui/core/store";
|
|
4
|
-
import { resource,
|
|
5
|
+
import { resource, withKey } from "@assistant-ui/tap";
|
|
5
6
|
//#region src/client/InMemoryThreadList.ts
|
|
6
7
|
const RESOLVED_PROMISE = Promise.resolve();
|
|
7
|
-
const ThreadListItemClient = resource((props)
|
|
8
|
+
const ThreadListItemClient = resource(function ThreadListItemClient(props) {
|
|
8
9
|
const { data, onSwitchTo, onUpdateCustom, onArchive, onUnarchive, onDelete } = props;
|
|
9
|
-
const state =
|
|
10
|
+
const state = useMemo(() => ({
|
|
10
11
|
id: data.id,
|
|
11
12
|
remoteId: void 0,
|
|
12
13
|
externalId: void 0,
|
|
@@ -35,10 +36,10 @@ const ThreadListItemClient = resource((props) => {
|
|
|
35
36
|
detach: () => {}
|
|
36
37
|
};
|
|
37
38
|
});
|
|
38
|
-
const InMemoryThreadList = resource((props)
|
|
39
|
+
const InMemoryThreadList = resource(function InMemoryThreadList(props) {
|
|
39
40
|
const { thread: threadFactory, onSwitchToThread, onSwitchToNewThread } = props;
|
|
40
|
-
const [mainThreadId, setMainThreadId] =
|
|
41
|
-
const [threads, setThreads] =
|
|
41
|
+
const [mainThreadId, setMainThreadId] = useState("main");
|
|
42
|
+
const [threads, setThreads] = useState(() => [{
|
|
42
43
|
id: "main",
|
|
43
44
|
title: "Main Thread",
|
|
44
45
|
status: "regular"
|
|
@@ -79,7 +80,7 @@ const InMemoryThreadList = resource((props) => {
|
|
|
79
80
|
setMainThreadId(newId);
|
|
80
81
|
onSwitchToNewThread?.();
|
|
81
82
|
};
|
|
82
|
-
const threadListItems =
|
|
83
|
+
const threadListItems = useClientLookup(() => threads.map((t) => withKey(t.id, ThreadListItemClient({
|
|
83
84
|
data: t,
|
|
84
85
|
onSwitchTo: () => handleSwitchToThread(t.id),
|
|
85
86
|
onUpdateCustom: (custom) => handleUpdateCustom(t.id, custom),
|
|
@@ -87,8 +88,8 @@ const InMemoryThreadList = resource((props) => {
|
|
|
87
88
|
onUnarchive: () => handleUnarchive(t.id),
|
|
88
89
|
onDelete: () => handleDelete(t.id)
|
|
89
90
|
}))), [threads]);
|
|
90
|
-
const mainThreadClient =
|
|
91
|
-
const state =
|
|
91
|
+
const mainThreadClient = useClientResource(threadFactory(mainThreadId));
|
|
92
|
+
const state = useMemo(() => {
|
|
92
93
|
const regularThreads = threads.filter((t) => t.status === "regular");
|
|
93
94
|
const archivedThreads = threads.filter((t) => t.status === "archived");
|
|
94
95
|
return {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"InMemoryThreadList.js","names":[],"sources":["../../src/client/InMemoryThreadList.ts"],"sourcesContent":["import { resource, tapState, tapMemo } from \"@assistant-ui/tap\";\nimport {\n type ClientOutput,\n tapClientLookup,\n Derived,\n attachTransformScopes,\n tapClientResource,\n} from \"@assistant-ui/store\";\nimport { withKey } from \"@assistant-ui/tap\";\nimport type { ResourceElement } from \"@assistant-ui/tap\";\n\nimport { ModelContext, Suggestions } from \"@assistant-ui/core/store\";\nimport { Tools, DataRenderers } from \"@assistant-ui/core/react\";\n\nconst RESOLVED_PROMISE = Promise.resolve();\n\nexport type InMemoryThreadListProps = {\n thread: (threadId: string) => ResourceElement<ClientOutput<\"thread\">>;\n onSwitchToThread?: (threadId: string) => void;\n onSwitchToNewThread?: () => void;\n};\n\ntype ThreadData = {\n id: string;\n title?: string;\n status: \"regular\" | \"archived\";\n custom?: Record<string, unknown> | undefined;\n};\n\n// ThreadListItem Client\nconst ThreadListItemClient = resource(\n (props: {\n data: ThreadData;\n onSwitchTo: () => void;\n onUpdateCustom: (custom: Record<string, unknown> | undefined) => void;\n onArchive: () => void;\n onUnarchive: () => void;\n onDelete: () => void;\n }): ClientOutput<\"threadListItem\"> => {\n const {\n data,\n onSwitchTo,\n onUpdateCustom,\n onArchive,\n onUnarchive,\n onDelete,\n } = props;\n const state = tapMemo(\n () => ({\n id: data.id,\n remoteId: undefined,\n externalId: undefined,\n title: data.title,\n status: data.status,\n custom: data.custom,\n }),\n [data.id, data.title, data.status, data.custom],\n );\n\n return {\n getState: () => state,\n switchTo: onSwitchTo,\n rename: () => {},\n updateCustom: onUpdateCustom,\n archive: onArchive,\n unarchive: onUnarchive,\n delete: onDelete,\n generateTitle: () => {},\n initialize: async () => ({ remoteId: data.id, externalId: undefined }),\n detach: () => {},\n };\n },\n);\n\n// InMemoryThreadList Client\nexport const InMemoryThreadList = resource(\n (props: InMemoryThreadListProps): ClientOutput<\"threads\"> => {\n const {\n thread: threadFactory,\n onSwitchToThread,\n onSwitchToNewThread,\n } = props;\n\n const [mainThreadId, setMainThreadId] = tapState(\"main\");\n const [threads, setThreads] = tapState<readonly ThreadData[]>(() => [\n { id: \"main\", title: \"Main Thread\", status: \"regular\" },\n ]);\n\n const handleSwitchToThread = (threadId: string) => {\n setMainThreadId(threadId);\n onSwitchToThread?.(threadId);\n };\n\n const handleArchive = (threadId: string) => {\n setThreads((prev) =>\n prev.map((t) =>\n t.id === threadId ? { ...t, status: \"archived\" as const } : t,\n ),\n );\n };\n\n const handleUnarchive = (threadId: string) => {\n setThreads((prev) =>\n prev.map((t) =>\n t.id === threadId ? { ...t, status: \"regular\" as const } : t,\n ),\n );\n };\n\n const handleUpdateCustom = (\n threadId: string,\n custom: Record<string, unknown> | undefined,\n ) => {\n setThreads((prev) =>\n prev.map((t) => (t.id === threadId ? { ...t, custom } : t)),\n );\n };\n\n const handleDelete = (threadId: string) => {\n setThreads((prev) => prev.filter((t) => t.id !== threadId));\n if (mainThreadId === threadId) {\n const remaining = threads.filter((t) => t.id !== threadId);\n setMainThreadId(remaining[0]?.id || \"main\");\n }\n };\n\n const handleSwitchToNewThread = () => {\n const newId = `thread-${Date.now()}`;\n setThreads((prev) => [\n ...prev,\n { id: newId, title: \"New Thread\", status: \"regular\" },\n ]);\n setMainThreadId(newId);\n onSwitchToNewThread?.();\n };\n\n const threadListItems = tapClientLookup(\n () =>\n threads.map((t) =>\n withKey(\n t.id,\n ThreadListItemClient({\n data: t,\n onSwitchTo: () => handleSwitchToThread(t.id),\n onUpdateCustom: (custom) => handleUpdateCustom(t.id, custom),\n onArchive: () => handleArchive(t.id),\n onUnarchive: () => handleUnarchive(t.id),\n onDelete: () => handleDelete(t.id),\n }),\n ),\n ),\n [threads],\n );\n\n // Create the main thread\n const mainThreadClient = tapClientResource(threadFactory(mainThreadId));\n\n const state = tapMemo(() => {\n const regularThreads = threads.filter((t) => t.status === \"regular\");\n const archivedThreads = threads.filter((t) => t.status === \"archived\");\n\n return {\n mainThreadId,\n newThreadId: null,\n isLoading: false,\n isLoadingMore: false,\n hasMore: false,\n threadIds: regularThreads.map((t) => t.id),\n archivedThreadIds: archivedThreads.map((t) => t.id),\n threadItems: threadListItems.state,\n main: mainThreadClient.state,\n };\n }, [mainThreadId, threads, threadListItems.state, mainThreadClient.state]);\n\n return {\n getState: () => state,\n switchToThread: handleSwitchToThread,\n switchToNewThread: handleSwitchToNewThread,\n getLoadThreadsPromise: () => RESOLVED_PROMISE,\n reload: () => RESOLVED_PROMISE,\n loadMore: () => RESOLVED_PROMISE,\n item: (selector) => {\n if (selector === \"main\") {\n const index = threads.findIndex((t) => t.id === mainThreadId);\n return threadListItems.get({ index: index === -1 ? 0 : index });\n }\n if (\"id\" in selector) {\n const index = threads.findIndex((t) => t.id === selector.id);\n return threadListItems.get({ index });\n }\n return threadListItems.get(selector);\n },\n thread: () => mainThreadClient.methods,\n };\n },\n);\n\nattachTransformScopes(InMemoryThreadList, (scopes, parent) => {\n scopes.thread ??= Derived({\n source: \"threads\",\n query: { type: \"main\" },\n get: (aui) => aui.threads().thread(\"main\"),\n });\n scopes.threadListItem ??= Derived({\n source: \"threads\",\n query: { type: \"main\" },\n get: (aui) => aui.threads().item(\"main\"),\n });\n scopes.composer ??= Derived({\n source: \"thread\",\n query: {},\n get: (aui) => aui.threads().thread(\"main\").composer(),\n });\n\n if (!scopes.modelContext && parent.modelContext.source === null) {\n scopes.modelContext = ModelContext();\n }\n if (!scopes.tools && parent.tools.source === null) {\n scopes.tools = Tools({});\n }\n if (!scopes.dataRenderers && parent.dataRenderers.source === null) {\n scopes.dataRenderers = DataRenderers();\n }\n if (!scopes.suggestions && parent.suggestions.source === null) {\n scopes.suggestions = Suggestions();\n }\n});\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"InMemoryThreadList.js","names":[],"sources":["../../src/client/InMemoryThreadList.ts"],"sourcesContent":["import { useState, useMemo } from \"react\";\nimport { resource, withKey, type ResourceElement } from \"@assistant-ui/tap\";\nimport {\n type ClientOutput,\n useClientLookup,\n Derived,\n attachTransformScopes,\n useClientResource,\n} from \"@assistant-ui/store\";\n\nimport { ModelContext, Suggestions } from \"@assistant-ui/core/store\";\nimport { Tools, DataRenderers } from \"@assistant-ui/core/react\";\n\nconst RESOLVED_PROMISE = Promise.resolve();\n\nexport type InMemoryThreadListProps = {\n thread: (threadId: string) => ResourceElement<ClientOutput<\"thread\">>;\n onSwitchToThread?: (threadId: string) => void;\n onSwitchToNewThread?: () => void;\n};\n\ntype ThreadData = {\n id: string;\n title?: string;\n status: \"regular\" | \"archived\";\n custom?: Record<string, unknown> | undefined;\n};\n\n// ThreadListItem Client\nconst ThreadListItemClient = resource(function ThreadListItemClient(props: {\n data: ThreadData;\n onSwitchTo: () => void;\n onUpdateCustom: (custom: Record<string, unknown> | undefined) => void;\n onArchive: () => void;\n onUnarchive: () => void;\n onDelete: () => void;\n}): ClientOutput<\"threadListItem\"> {\n const { data, onSwitchTo, onUpdateCustom, onArchive, onUnarchive, onDelete } =\n props;\n const state = useMemo(\n () => ({\n id: data.id,\n remoteId: undefined,\n externalId: undefined,\n title: data.title,\n status: data.status,\n custom: data.custom,\n }),\n [data.id, data.title, data.status, data.custom],\n );\n\n return {\n getState: () => state,\n switchTo: onSwitchTo,\n rename: () => {},\n updateCustom: onUpdateCustom,\n archive: onArchive,\n unarchive: onUnarchive,\n delete: onDelete,\n generateTitle: () => {},\n initialize: async () => ({ remoteId: data.id, externalId: undefined }),\n detach: () => {},\n };\n});\n\n// InMemoryThreadList Client\nexport const InMemoryThreadList = resource(function InMemoryThreadList(\n props: InMemoryThreadListProps,\n): ClientOutput<\"threads\"> {\n const {\n thread: threadFactory,\n onSwitchToThread,\n onSwitchToNewThread,\n } = props;\n\n const [mainThreadId, setMainThreadId] = useState(\"main\");\n const [threads, setThreads] = useState<readonly ThreadData[]>(() => [\n { id: \"main\", title: \"Main Thread\", status: \"regular\" },\n ]);\n\n const handleSwitchToThread = (threadId: string) => {\n setMainThreadId(threadId);\n onSwitchToThread?.(threadId);\n };\n\n const handleArchive = (threadId: string) => {\n setThreads((prev) =>\n prev.map((t) =>\n t.id === threadId ? { ...t, status: \"archived\" as const } : t,\n ),\n );\n };\n\n const handleUnarchive = (threadId: string) => {\n setThreads((prev) =>\n prev.map((t) =>\n t.id === threadId ? { ...t, status: \"regular\" as const } : t,\n ),\n );\n };\n\n const handleUpdateCustom = (\n threadId: string,\n custom: Record<string, unknown> | undefined,\n ) => {\n setThreads((prev) =>\n prev.map((t) => (t.id === threadId ? { ...t, custom } : t)),\n );\n };\n\n const handleDelete = (threadId: string) => {\n setThreads((prev) => prev.filter((t) => t.id !== threadId));\n if (mainThreadId === threadId) {\n const remaining = threads.filter((t) => t.id !== threadId);\n setMainThreadId(remaining[0]?.id || \"main\");\n }\n };\n\n const handleSwitchToNewThread = () => {\n const newId = `thread-${Date.now()}`;\n setThreads((prev) => [\n ...prev,\n { id: newId, title: \"New Thread\", status: \"regular\" },\n ]);\n setMainThreadId(newId);\n onSwitchToNewThread?.();\n };\n\n const threadListItems = useClientLookup(\n () =>\n threads.map((t) =>\n withKey(\n t.id,\n ThreadListItemClient({\n data: t,\n onSwitchTo: () => handleSwitchToThread(t.id),\n onUpdateCustom: (custom) => handleUpdateCustom(t.id, custom),\n onArchive: () => handleArchive(t.id),\n onUnarchive: () => handleUnarchive(t.id),\n onDelete: () => handleDelete(t.id),\n }),\n ),\n ),\n [threads],\n );\n\n // Create the main thread\n const mainThreadClient = useClientResource(threadFactory(mainThreadId));\n\n const state = useMemo(() => {\n const regularThreads = threads.filter((t) => t.status === \"regular\");\n const archivedThreads = threads.filter((t) => t.status === \"archived\");\n\n return {\n mainThreadId,\n newThreadId: null,\n isLoading: false,\n isLoadingMore: false,\n hasMore: false,\n threadIds: regularThreads.map((t) => t.id),\n archivedThreadIds: archivedThreads.map((t) => t.id),\n threadItems: threadListItems.state,\n main: mainThreadClient.state,\n };\n }, [mainThreadId, threads, threadListItems.state, mainThreadClient.state]);\n\n return {\n getState: () => state,\n switchToThread: handleSwitchToThread,\n switchToNewThread: handleSwitchToNewThread,\n getLoadThreadsPromise: () => RESOLVED_PROMISE,\n reload: () => RESOLVED_PROMISE,\n loadMore: () => RESOLVED_PROMISE,\n item: (selector) => {\n if (selector === \"main\") {\n const index = threads.findIndex((t) => t.id === mainThreadId);\n return threadListItems.get({ index: index === -1 ? 0 : index });\n }\n if (\"id\" in selector) {\n const index = threads.findIndex((t) => t.id === selector.id);\n return threadListItems.get({ index });\n }\n return threadListItems.get(selector);\n },\n thread: () => mainThreadClient.methods,\n };\n});\n\nattachTransformScopes(InMemoryThreadList, (scopes, parent) => {\n scopes.thread ??= Derived({\n source: \"threads\",\n query: { type: \"main\" },\n get: (aui) => aui.threads().thread(\"main\"),\n });\n scopes.threadListItem ??= Derived({\n source: \"threads\",\n query: { type: \"main\" },\n get: (aui) => aui.threads().item(\"main\"),\n });\n scopes.composer ??= Derived({\n source: \"thread\",\n query: {},\n get: (aui) => aui.threads().thread(\"main\").composer(),\n });\n\n if (!scopes.modelContext && parent.modelContext.source === null) {\n scopes.modelContext = ModelContext();\n }\n if (!scopes.tools && parent.tools.source === null) {\n scopes.tools = Tools({});\n }\n if (!scopes.dataRenderers && parent.dataRenderers.source === null) {\n scopes.dataRenderers = DataRenderers();\n }\n if (!scopes.suggestions && parent.suggestions.source === null) {\n scopes.suggestions = Suggestions();\n }\n});\n"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SingleThreadList.d.ts","names":[],"sources":["../../src/client/SingleThreadList.ts"],"mappings":";;;
|
|
1
|
+
{"version":3,"file":"SingleThreadList.d.ts","names":[],"sources":["../../src/client/SingleThreadList.ts"],"mappings":";;;KAqCK,qBAAA;EACH,MAAA,EAAQ,aAAa;AAAA;;;;AAAA;AAQvB;cAAa,gBAAA,GAAgB,KAAA,EAAA,qBAAA,iCAAA,eAAA,CAAA,YAAA,aAAA,qBAAA"}
|
|
@@ -1,10 +1,11 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
1
|
+
import { useClientResource } from "@assistant-ui/store";
|
|
2
|
+
import { useMemo, useState } from "@assistant-ui/tap/react-shim";
|
|
3
|
+
import { resource } from "@assistant-ui/tap";
|
|
3
4
|
//#region src/client/SingleThreadList.ts
|
|
4
5
|
const RESOLVED_PROMISE = Promise.resolve();
|
|
5
6
|
const THREAD_ID = "default";
|
|
6
|
-
const SingleThreadListItem = resource(()
|
|
7
|
-
const [custom, setCustom] =
|
|
7
|
+
const SingleThreadListItem = resource(function SingleThreadListItem() {
|
|
8
|
+
const [custom, setCustom] = useState();
|
|
8
9
|
return {
|
|
9
10
|
getState: () => ({
|
|
10
11
|
id: THREAD_ID,
|
|
@@ -33,10 +34,10 @@ const SingleThreadListItem = resource(() => {
|
|
|
33
34
|
* Automatically provided by ExternalThread when no threads scope exists.
|
|
34
35
|
* Mounts the provided thread resource element.
|
|
35
36
|
*/
|
|
36
|
-
const SingleThreadList = resource(({ thread })
|
|
37
|
-
const itemClient =
|
|
38
|
-
const threadClient =
|
|
39
|
-
const state =
|
|
37
|
+
const SingleThreadList = resource(function SingleThreadList({ thread }) {
|
|
38
|
+
const itemClient = useClientResource(SingleThreadListItem());
|
|
39
|
+
const threadClient = useClientResource(thread);
|
|
40
|
+
const state = useMemo(() => ({
|
|
40
41
|
mainThreadId: THREAD_ID,
|
|
41
42
|
newThreadId: null,
|
|
42
43
|
isLoading: false,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SingleThreadList.js","names":[],"sources":["../../src/client/SingleThreadList.ts"],"sourcesContent":["import {
|
|
1
|
+
{"version":3,"file":"SingleThreadList.js","names":[],"sources":["../../src/client/SingleThreadList.ts"],"sourcesContent":["import { useMemo, useState } from \"react\";\nimport { resource } from \"@assistant-ui/tap\";\nimport {\n type ClientElement,\n type ClientOutput,\n useClientResource,\n} from \"@assistant-ui/store\";\n\nconst RESOLVED_PROMISE = Promise.resolve();\nconst THREAD_ID = \"default\";\n\nconst SingleThreadListItem = resource(\n function SingleThreadListItem(): ClientOutput<\"threadListItem\"> {\n const [custom, setCustom] = useState<Record<string, unknown> | undefined>();\n\n return {\n getState: () => ({\n id: THREAD_ID,\n remoteId: undefined,\n externalId: undefined,\n title: undefined,\n status: \"regular\",\n custom,\n }),\n switchTo: () => {},\n rename: () => {},\n updateCustom: setCustom,\n archive: () => {},\n unarchive: () => {},\n delete: () => {},\n generateTitle: () => {},\n initialize: async () => ({ remoteId: THREAD_ID, externalId: undefined }),\n detach: () => {},\n };\n },\n);\n\ntype SingleThreadListProps = {\n thread: ClientElement<\"thread\">;\n};\n\n/**\n * A minimal threads scope that wraps a single thread.\n * Automatically provided by ExternalThread when no threads scope exists.\n * Mounts the provided thread resource element.\n */\nexport const SingleThreadList = resource(function SingleThreadList({\n thread,\n}: SingleThreadListProps): ClientOutput<\"threads\"> {\n const itemClient = useClientResource(SingleThreadListItem());\n const threadClient = useClientResource(thread);\n\n const state = useMemo(\n () => ({\n mainThreadId: THREAD_ID,\n newThreadId: null,\n isLoading: false,\n isLoadingMore: false,\n hasMore: false,\n threadIds: [THREAD_ID],\n archivedThreadIds: [],\n threadItems: [itemClient.state],\n main: threadClient.state,\n }),\n [itemClient.state, threadClient.state],\n );\n\n return {\n getState: () => state,\n switchToThread: () => {\n throw new Error(\"SingleThreadList does not support switchToThread\");\n },\n switchToNewThread: () => {\n throw new Error(\"SingleThreadList does not support switchToNewThread\");\n },\n getLoadThreadsPromise: () => RESOLVED_PROMISE,\n reload: () => RESOLVED_PROMISE,\n loadMore: () => RESOLVED_PROMISE,\n item: (selector) => {\n if (\n selector !== \"main\" &&\n !(\n typeof selector === \"object\" &&\n \"id\" in selector &&\n selector.id === THREAD_ID\n ) &&\n !(\n typeof selector === \"object\" &&\n \"index\" in selector &&\n selector.index === 0\n )\n ) {\n throw new Error(\n `SingleThreadList: unknown item selector ${JSON.stringify(selector)}`,\n );\n }\n return itemClient.methods;\n },\n thread: (selector) => {\n if (selector !== \"main\" && selector !== THREAD_ID) {\n throw new Error(\n `SingleThreadList: unknown thread selector ${JSON.stringify(selector)}`,\n );\n }\n return threadClient.methods;\n },\n };\n});\n"],"mappings":";;;;AAQA,MAAM,mBAAmB,QAAQ,QAAQ;AACzC,MAAM,YAAY;AAElB,MAAM,uBAAuB,SAC3B,SAAS,uBAAuD;CAC9D,MAAM,CAAC,QAAQ,aAAa,SAA8C;CAE1E,OAAO;EACL,iBAAiB;GACf,IAAI;GACJ,UAAU,KAAA;GACV,YAAY,KAAA;GACZ,OAAO,KAAA;GACP,QAAQ;GACR;EACF;EACA,gBAAgB,CAAC;EACjB,cAAc,CAAC;EACf,cAAc;EACd,eAAe,CAAC;EAChB,iBAAiB,CAAC;EAClB,cAAc,CAAC;EACf,qBAAqB,CAAC;EACtB,YAAY,aAAa;GAAE,UAAU;GAAW,YAAY,KAAA;EAAU;EACtE,cAAc,CAAC;CACjB;AACF,CACF;;;;;;AAWA,MAAa,mBAAmB,SAAS,SAAS,iBAAiB,EACjE,UACiD;CACjD,MAAM,aAAa,kBAAkB,qBAAqB,CAAC;CAC3D,MAAM,eAAe,kBAAkB,MAAM;CAE7C,MAAM,QAAQ,eACL;EACL,cAAc;EACd,aAAa;EACb,WAAW;EACX,eAAe;EACf,SAAS;EACT,WAAW,CAAC,SAAS;EACrB,mBAAmB,CAAC;EACpB,aAAa,CAAC,WAAW,KAAK;EAC9B,MAAM,aAAa;CACrB,IACA,CAAC,WAAW,OAAO,aAAa,KAAK,CACvC;CAEA,OAAO;EACL,gBAAgB;EAChB,sBAAsB;GACpB,MAAM,IAAI,MAAM,kDAAkD;EACpE;EACA,yBAAyB;GACvB,MAAM,IAAI,MAAM,qDAAqD;EACvE;EACA,6BAA6B;EAC7B,cAAc;EACd,gBAAgB;EAChB,OAAO,aAAa;GAClB,IACE,aAAa,UACb,EACE,OAAO,aAAa,YACpB,QAAQ,YACR,SAAS,OAAO,cAElB,EACE,OAAO,aAAa,YACpB,WAAW,YACX,SAAS,UAAU,IAGrB,MAAM,IAAI,MACR,2CAA2C,KAAK,UAAU,QAAQ,GACpE;GAEF,OAAO,WAAW;EACpB;EACA,SAAS,aAAa;GACpB,IAAI,aAAa,UAAU,aAAa,WACtC,MAAM,IAAI,MACR,6CAA6C,KAAK,UAAU,QAAQ,GACtE;GAEF,OAAO,aAAa;EACtB;CACF;AACF,CAAC"}
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
import { makeThreadViewportStore } from "../stores/ThreadViewport.js";
|
|
3
3
|
import { ThreadViewportContext, useThreadViewportStore } from "../react/ThreadViewportContext.js";
|
|
4
4
|
import { writableStore } from "../ReadonlyStore.js";
|
|
5
|
-
import { useEffect, useState } from "react";
|
|
5
|
+
import { useEffect, useState } from "@assistant-ui/tap/react-shim";
|
|
6
6
|
import { jsx } from "react/jsx-runtime";
|
|
7
7
|
//#region src/context/providers/ThreadViewportProvider.tsx
|
|
8
8
|
const useThreadViewportStoreValue = (options) => {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ThreadViewportProvider.js","names":[],"sources":["../../../src/context/providers/ThreadViewportProvider.tsx"],"sourcesContent":["\"use client\";\n\nimport type
|
|
1
|
+
{"version":3,"file":"ThreadViewportProvider.js","names":[],"sources":["../../../src/context/providers/ThreadViewportProvider.tsx"],"sourcesContent":["\"use client\";\n\nimport { type FC, type PropsWithChildren, useEffect, useState } from \"react\";\n\nimport {\n makeThreadViewportStore,\n type ThreadViewportStoreOptions,\n} from \"../stores/ThreadViewport\";\nimport {\n ThreadViewportContext,\n type ThreadViewportContextValue,\n useThreadViewportStore,\n} from \"../react/ThreadViewportContext\";\nimport { writableStore } from \"../ReadonlyStore\";\n\nexport type ThreadViewportProviderProps = PropsWithChildren<{\n options?: ThreadViewportStoreOptions;\n}>;\n\nconst useThreadViewportStoreValue = (options: ThreadViewportStoreOptions) => {\n const outerViewport = useThreadViewportStore({ optional: true });\n // Viewport options are initial configuration. Keeping them non-reactive avoids\n // fanout through every message in long threads when anchoring config changes.\n const [store] = useState(() => makeThreadViewportStore(options));\n\n // Forward scrollToBottom from outer viewport to inner viewport\n useEffect(() => {\n return outerViewport?.getState().onScrollToBottom(() => {\n store.getState().scrollToBottom();\n });\n }, [outerViewport, store]);\n\n useEffect(() => {\n if (!outerViewport) return;\n return store.subscribe((state) => {\n if (outerViewport.getState().isAtBottom !== state.isAtBottom) {\n writableStore(outerViewport).setState({ isAtBottom: state.isAtBottom });\n }\n });\n }, [store, outerViewport]);\n\n return store;\n};\n\nexport const ThreadPrimitiveViewportProvider: FC<\n ThreadViewportProviderProps\n> = ({ children, options = {} }) => {\n const useThreadViewport = useThreadViewportStoreValue(options);\n\n const [context] = useState<ThreadViewportContextValue>(() => {\n return {\n useThreadViewport,\n };\n });\n\n return (\n <ThreadViewportContext.Provider value={context}>\n {children}\n </ThreadViewportContext.Provider>\n );\n};\n"],"mappings":";;;;;;;AAmBA,MAAM,+BAA+B,YAAwC;CAC3E,MAAM,gBAAgB,uBAAuB,EAAE,UAAU,KAAK,CAAC;CAG/D,MAAM,CAAC,SAAS,eAAe,wBAAwB,OAAO,CAAC;CAG/D,gBAAgB;EACd,OAAO,eAAe,SAAS,CAAC,CAAC,uBAAuB;GACtD,MAAM,SAAS,CAAC,CAAC,eAAe;EAClC,CAAC;CACH,GAAG,CAAC,eAAe,KAAK,CAAC;CAEzB,gBAAgB;EACd,IAAI,CAAC,eAAe;EACpB,OAAO,MAAM,WAAW,UAAU;GAChC,IAAI,cAAc,SAAS,CAAC,CAAC,eAAe,MAAM,YAChD,cAAc,aAAa,CAAC,CAAC,SAAS,EAAE,YAAY,MAAM,WAAW,CAAC;EAE1E,CAAC;CACH,GAAG,CAAC,OAAO,aAAa,CAAC;CAEzB,OAAO;AACT;AAEA,MAAa,mCAER,EAAE,UAAU,UAAU,CAAC,QAAQ;CAClC,MAAM,oBAAoB,4BAA4B,OAAO;CAE7D,MAAM,CAAC,WAAW,eAA2C;EAC3D,OAAO,EACL,kBACF;CACF,CAAC;CAED,OACE,oBAAC,sBAAsB,UAAvB;EAAgC,OAAO;EACpC;CAC6B,CAAA;AAEpC"}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import { createContextHook } from "./utils/createContextHook.js";
|
|
3
3
|
import { createContextStoreHook } from "./utils/createContextStoreHook.js";
|
|
4
|
-
import { createContext } from "react";
|
|
4
|
+
import { createContext } from "@assistant-ui/tap/react-shim";
|
|
5
5
|
//#region src/context/react/ThreadViewportContext.ts
|
|
6
6
|
const ThreadViewportContext = createContext(null);
|
|
7
7
|
const { useThreadViewport, useThreadViewportStore } = createContextStoreHook(createContextHook(ThreadViewportContext, "ThreadPrimitive.Viewport"), "useThreadViewport");
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ensureBinding.js","names":[],"sources":["../../../../src/context/react/utils/ensureBinding.ts"],"sourcesContent":["type Bindable = {\n __internal_bindMethods?: () => void;\n __isBound?: boolean;\n};\nconst debugVerifyPrototype = (\n runtime: Record<string, unknown>,\n prototype: any,\n) => {\n const unboundMethods = Object.getOwnPropertyNames(prototype).filter(\n (methodStr) => {\n const descriptor = Object.getOwnPropertyDescriptor(prototype, methodStr);\n const isMethod = descriptor && typeof descriptor.value === \"function\";\n if (!isMethod) return false;\n\n const methodName = methodStr as keyof typeof runtime | \"constructor\";\n return (\n isMethod &&\n !methodName.startsWith(\"_\") &&\n methodName !== \"constructor\" &&\n prototype[methodName] === runtime[methodName]\n );\n },\n );\n\n if (unboundMethods.length > 0) {\n throw new Error(\n `The following methods are not bound: ${JSON.stringify(unboundMethods)}`,\n );\n }\n\n const prototypePrototype = Object.getPrototypeOf(prototype);\n if (prototypePrototype && prototypePrototype !== Object.prototype) {\n debugVerifyPrototype(runtime, prototypePrototype);\n }\n};\nexport const ensureBinding = (r: unknown) => {\n const runtime = r as Bindable;\n if (runtime.__isBound) return;\n\n runtime.__internal_bindMethods?.();\n runtime.__isBound = true;\n\n if (process.env.NODE_ENV !== \"production\") {\n debugVerifyPrototype(runtime, Object.getPrototypeOf(runtime));\n }\n};\n"],"mappings":";AAIA,MAAM,wBACJ,SACA,cACG;CACH,MAAM,iBAAiB,OAAO,oBAAoB,SAAS,
|
|
1
|
+
{"version":3,"file":"ensureBinding.js","names":[],"sources":["../../../../src/context/react/utils/ensureBinding.ts"],"sourcesContent":["type Bindable = {\n __internal_bindMethods?: () => void;\n __isBound?: boolean;\n};\nconst debugVerifyPrototype = (\n runtime: Record<string, unknown>,\n prototype: any,\n) => {\n const unboundMethods = Object.getOwnPropertyNames(prototype).filter(\n (methodStr) => {\n const descriptor = Object.getOwnPropertyDescriptor(prototype, methodStr);\n const isMethod = descriptor && typeof descriptor.value === \"function\";\n if (!isMethod) return false;\n\n const methodName = methodStr as keyof typeof runtime | \"constructor\";\n return (\n isMethod &&\n !methodName.startsWith(\"_\") &&\n methodName !== \"constructor\" &&\n prototype[methodName] === runtime[methodName]\n );\n },\n );\n\n if (unboundMethods.length > 0) {\n throw new Error(\n `The following methods are not bound: ${JSON.stringify(unboundMethods)}`,\n );\n }\n\n const prototypePrototype = Object.getPrototypeOf(prototype);\n if (prototypePrototype && prototypePrototype !== Object.prototype) {\n debugVerifyPrototype(runtime, prototypePrototype);\n }\n};\nexport const ensureBinding = (r: unknown) => {\n const runtime = r as Bindable;\n if (runtime.__isBound) return;\n\n runtime.__internal_bindMethods?.();\n runtime.__isBound = true;\n\n if (process.env.NODE_ENV !== \"production\") {\n debugVerifyPrototype(runtime, Object.getPrototypeOf(runtime));\n }\n};\n"],"mappings":";AAIA,MAAM,wBACJ,SACA,cACG;CACH,MAAM,iBAAiB,OAAO,oBAAoB,SAAS,CAAC,CAAC,QAC1D,cAAc;EACb,MAAM,aAAa,OAAO,yBAAyB,WAAW,SAAS;EACvE,MAAM,WAAW,cAAc,OAAO,WAAW,UAAU;EAC3D,IAAI,CAAC,UAAU,OAAO;EAEtB,MAAM,aAAa;EACnB,OACE,YACA,CAAC,WAAW,WAAW,GAAG,KAC1B,eAAe,iBACf,UAAU,gBAAgB,QAAQ;CAEtC,CACF;CAEA,IAAI,eAAe,SAAS,GAC1B,MAAM,IAAI,MACR,wCAAwC,KAAK,UAAU,cAAc,GACvE;CAGF,MAAM,qBAAqB,OAAO,eAAe,SAAS;CAC1D,IAAI,sBAAsB,uBAAuB,OAAO,WACtD,qBAAqB,SAAS,kBAAkB;AAEpD;AACA,MAAa,iBAAiB,MAAe;CAC3C,MAAM,UAAU;CAChB,IAAI,QAAQ,WAAW;CAEvB,QAAQ,yBAAyB;CACjC,QAAQ,YAAY;CAEpB,IAAI,QAAQ,IAAI,aAAa,cAC3B,qBAAqB,SAAS,OAAO,eAAe,OAAO,CAAC;AAEhE"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { ensureBinding } from "./ensureBinding.js";
|
|
2
|
-
import { useDebugValue, useSyncExternalStore } from "react";
|
|
2
|
+
import { useDebugValue, useSyncExternalStore } from "@assistant-ui/tap/react-shim";
|
|
3
3
|
//#region src/context/react/utils/useRuntimeState.ts
|
|
4
4
|
function useRuntimeStateInternal(runtime, selector = identity) {
|
|
5
5
|
ensureBinding(runtime);
|