@assistant-ui/react 0.11.35 → 0.11.37
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/dist/client/AssistantClient.d.ts +13 -57
- package/dist/client/AssistantClient.d.ts.map +1 -1
- package/dist/client/AssistantClient.js +49 -26
- package/dist/client/AssistantClient.js.map +1 -1
- package/dist/client/ModelContext.d.ts +8 -0
- package/dist/client/ModelContext.d.ts.map +1 -0
- package/dist/client/ModelContext.js +21 -0
- package/dist/client/ModelContext.js.map +1 -0
- package/dist/client/ModelContextClient.d.ts +7 -0
- package/dist/client/ModelContextClient.d.ts.map +1 -0
- package/dist/client/ModelContextClient.js +18 -0
- package/dist/client/ModelContextClient.js.map +1 -0
- package/dist/client/ToolUIClient.d.ts.map +1 -1
- package/dist/client/ToolUIClient.js +45 -3
- package/dist/client/ToolUIClient.js.map +1 -1
- package/dist/client/ToolUIContext.d.ts +4 -0
- package/dist/client/ToolUIContext.d.ts.map +1 -0
- package/dist/client/ToolUIContext.js +20 -0
- package/dist/client/ToolUIContext.js.map +1 -0
- package/dist/client/Tools.d.ts +10 -0
- package/dist/client/Tools.d.ts.map +1 -0
- package/dist/client/Tools.js +55 -0
- package/dist/client/Tools.js.map +1 -0
- package/dist/client/types/ModelContext.d.ts +12 -0
- package/dist/client/types/ModelContext.d.ts.map +1 -0
- package/dist/client/types/ModelContext.js +1 -0
- package/dist/client/types/ModelContext.js.map +1 -0
- package/dist/client/types/ThreadList.d.ts.map +1 -1
- package/dist/client/types/ToolUI.d.ts +12 -1
- package/dist/client/types/ToolUI.d.ts.map +1 -1
- package/dist/client/types/Tools.d.ts +9 -0
- package/dist/client/types/Tools.d.ts.map +1 -0
- package/dist/client/types/Tools.js +1 -0
- package/dist/client/types/Tools.js.map +1 -0
- package/dist/context/providers/AttachmentByIndexProvider.d.ts.map +1 -1
- package/dist/context/providers/AttachmentByIndexProvider.js +20 -24
- package/dist/context/providers/AttachmentByIndexProvider.js.map +1 -1
- package/dist/context/providers/MessageByIndexProvider.d.ts.map +1 -1
- package/dist/context/providers/MessageByIndexProvider.js +27 -29
- package/dist/context/providers/MessageByIndexProvider.js.map +1 -1
- package/dist/context/providers/MessageProvider.d.ts.map +1 -1
- package/dist/context/providers/MessageProvider.js +11 -13
- package/dist/context/providers/MessageProvider.js.map +1 -1
- package/dist/context/providers/PartByIndexProvider.d.ts.map +1 -1
- package/dist/context/providers/PartByIndexProvider.js +11 -13
- package/dist/context/providers/PartByIndexProvider.js.map +1 -1
- package/dist/context/providers/TextMessagePartProvider.d.ts.map +1 -1
- package/dist/context/providers/TextMessagePartProvider.js +11 -13
- package/dist/context/providers/TextMessagePartProvider.js.map +1 -1
- package/dist/context/providers/ThreadListItemProvider.d.ts.map +1 -1
- package/dist/context/providers/ThreadListItemProvider.js +41 -45
- package/dist/context/providers/ThreadListItemProvider.js.map +1 -1
- package/dist/context/react/AssistantApiContext.d.ts +33 -4
- package/dist/context/react/AssistantApiContext.d.ts.map +1 -1
- package/dist/context/react/AssistantApiContext.js +35 -17
- package/dist/context/react/AssistantApiContext.js.map +1 -1
- package/dist/context/react/index.d.ts +1 -1
- package/dist/context/react/index.d.ts.map +1 -1
- package/dist/context/react/index.js +5 -1
- package/dist/context/react/index.js.map +1 -1
- package/dist/legacy-runtime/AssistantRuntimeProvider.d.ts.map +1 -1
- package/dist/legacy-runtime/AssistantRuntimeProvider.js +7 -9
- package/dist/legacy-runtime/AssistantRuntimeProvider.js.map +1 -1
- package/dist/legacy-runtime/RuntimeAdapter.d.ts +7 -0
- package/dist/legacy-runtime/RuntimeAdapter.d.ts.map +1 -0
- package/dist/legacy-runtime/RuntimeAdapter.js +20 -0
- package/dist/legacy-runtime/RuntimeAdapter.js.map +1 -0
- package/dist/legacy-runtime/client/ThreadListRuntimeClient.d.ts +2 -0
- package/dist/legacy-runtime/client/ThreadListRuntimeClient.d.ts.map +1 -1
- package/dist/legacy-runtime/client/ThreadListRuntimeClient.js +6 -2
- package/dist/legacy-runtime/client/ThreadListRuntimeClient.js.map +1 -1
- package/dist/legacy-runtime/hooks/AssistantContext.d.ts +14 -1
- package/dist/legacy-runtime/hooks/AssistantContext.d.ts.map +1 -1
- package/dist/legacy-runtime/hooks/AssistantContext.js +1 -1
- package/dist/legacy-runtime/hooks/AssistantContext.js.map +1 -1
- package/dist/legacy-runtime/hooks/AttachmentContext.d.ts +6 -0
- package/dist/legacy-runtime/hooks/AttachmentContext.d.ts.map +1 -1
- package/dist/legacy-runtime/hooks/AttachmentContext.js.map +1 -1
- package/dist/legacy-runtime/hooks/ComposerContext.d.ts +41 -2
- package/dist/legacy-runtime/hooks/ComposerContext.d.ts.map +1 -1
- package/dist/legacy-runtime/hooks/ComposerContext.js.map +1 -1
- package/dist/legacy-runtime/hooks/MessageContext.d.ts +36 -2
- package/dist/legacy-runtime/hooks/MessageContext.d.ts.map +1 -1
- package/dist/legacy-runtime/hooks/MessageContext.js.map +1 -1
- package/dist/legacy-runtime/hooks/MessagePartContext.d.ts +6 -0
- package/dist/legacy-runtime/hooks/MessagePartContext.d.ts.map +1 -1
- package/dist/legacy-runtime/hooks/MessagePartContext.js.map +1 -1
- package/dist/legacy-runtime/hooks/ThreadContext.d.ts +26 -1
- package/dist/legacy-runtime/hooks/ThreadContext.d.ts.map +1 -1
- package/dist/legacy-runtime/hooks/ThreadContext.js.map +1 -1
- package/dist/legacy-runtime/hooks/ThreadListItemContext.d.ts +6 -0
- package/dist/legacy-runtime/hooks/ThreadListItemContext.d.ts.map +1 -1
- package/dist/legacy-runtime/hooks/ThreadListItemContext.js.map +1 -1
- package/dist/legacy-runtime/runtime-cores/core/AssistantRuntimeCore.d.ts +1 -0
- package/dist/legacy-runtime/runtime-cores/core/AssistantRuntimeCore.d.ts.map +1 -1
- package/dist/legacy-runtime/runtime-cores/core/BaseAssistantRuntimeCore.d.ts +1 -0
- package/dist/legacy-runtime/runtime-cores/core/BaseAssistantRuntimeCore.d.ts.map +1 -1
- package/dist/legacy-runtime/runtime-cores/core/BaseAssistantRuntimeCore.js +3 -0
- package/dist/legacy-runtime/runtime-cores/core/BaseAssistantRuntimeCore.js.map +1 -1
- package/dist/legacy-runtime/runtime-cores/external-store/ExternalStoreThreadListRuntimeCore.d.ts +4 -1
- package/dist/legacy-runtime/runtime-cores/external-store/ExternalStoreThreadListRuntimeCore.d.ts.map +1 -1
- package/dist/legacy-runtime/runtime-cores/external-store/ExternalStoreThreadListRuntimeCore.js +2 -2
- package/dist/legacy-runtime/runtime-cores/external-store/ExternalStoreThreadListRuntimeCore.js.map +1 -1
- package/dist/legacy-runtime/runtime-cores/external-store/ExternalStoreThreadRuntimeCore.d.ts.map +1 -1
- package/dist/legacy-runtime/runtime-cores/external-store/ExternalStoreThreadRuntimeCore.js +7 -1
- package/dist/legacy-runtime/runtime-cores/external-store/ExternalStoreThreadRuntimeCore.js.map +1 -1
- package/dist/legacy-runtime/runtime-cores/external-store/auto-status.d.ts +2 -12
- package/dist/legacy-runtime/runtime-cores/external-store/auto-status.d.ts.map +1 -1
- package/dist/legacy-runtime/runtime-cores/external-store/auto-status.js +45 -15
- package/dist/legacy-runtime/runtime-cores/external-store/auto-status.js.map +1 -1
- package/dist/legacy-runtime/runtime-cores/external-store/external-message-converter.d.ts +2 -0
- package/dist/legacy-runtime/runtime-cores/external-store/external-message-converter.d.ts.map +1 -1
- package/dist/legacy-runtime/runtime-cores/external-store/external-message-converter.js +4 -2
- package/dist/legacy-runtime/runtime-cores/external-store/external-message-converter.js.map +1 -1
- package/dist/legacy-runtime/runtime-cores/local/LocalThreadListRuntimeCore.d.ts +4 -1
- package/dist/legacy-runtime/runtime-cores/local/LocalThreadListRuntimeCore.d.ts.map +1 -1
- package/dist/legacy-runtime/runtime-cores/local/LocalThreadListRuntimeCore.js +2 -2
- package/dist/legacy-runtime/runtime-cores/local/LocalThreadListRuntimeCore.js.map +1 -1
- package/dist/legacy-runtime/runtime-cores/utils/MessageRepository.js +1 -1
- package/dist/legacy-runtime/runtime-cores/utils/MessageRepository.js.map +1 -1
- package/dist/model-context/index.d.ts +2 -0
- package/dist/model-context/index.d.ts.map +1 -1
- package/dist/model-context/index.js +6 -0
- package/dist/model-context/index.js.map +1 -1
- package/dist/model-context/makeAssistantVisible.js +1 -1
- package/dist/model-context/makeAssistantVisible.js.map +1 -1
- package/dist/model-context/toolbox.d.ts +28 -0
- package/dist/model-context/toolbox.d.ts.map +1 -0
- package/dist/model-context/toolbox.js +15 -0
- package/dist/model-context/toolbox.js.map +1 -0
- package/dist/model-context/useAssistantInstructions.js +1 -1
- package/dist/model-context/useAssistantInstructions.js.map +1 -1
- package/dist/model-context/useAssistantTool.js +1 -1
- package/dist/model-context/useAssistantTool.js.map +1 -1
- package/dist/primitives/index.d.ts +1 -0
- package/dist/primitives/index.d.ts.map +1 -1
- package/dist/primitives/index.js +2 -0
- package/dist/primitives/index.js.map +1 -1
- package/dist/primitives/message/MessageParts.d.ts +31 -1
- package/dist/primitives/message/MessageParts.d.ts.map +1 -1
- package/dist/primitives/message/MessageParts.js +68 -25
- package/dist/primitives/message/MessageParts.js.map +1 -1
- package/dist/primitives/message/MessagePartsGrouped.d.ts.map +1 -1
- package/dist/primitives/message/MessagePartsGrouped.js +2 -2
- package/dist/primitives/message/MessagePartsGrouped.js.map +1 -1
- package/dist/primitives/reasoning/index.d.ts +2 -0
- package/dist/primitives/reasoning/index.d.ts.map +1 -0
- package/dist/primitives/reasoning/index.js +6 -0
- package/dist/primitives/reasoning/index.js.map +1 -0
- package/dist/primitives/reasoning/useScrollLock.d.ts +29 -0
- package/dist/primitives/reasoning/useScrollLock.d.ts.map +1 -0
- package/dist/primitives/reasoning/useScrollLock.js +50 -0
- package/dist/primitives/reasoning/useScrollLock.js.map +1 -0
- package/dist/tests/setup.js +7 -7
- package/dist/tests/setup.js.map +1 -1
- package/dist/types/MessagePartComponentTypes.d.ts +6 -1
- package/dist/types/MessagePartComponentTypes.d.ts.map +1 -1
- package/dist/types/index.d.ts +1 -1
- package/dist/types/index.d.ts.map +1 -1
- package/dist/utils/tap-store/derived-scopes.d.ts +81 -0
- package/dist/utils/tap-store/derived-scopes.d.ts.map +1 -0
- package/dist/utils/tap-store/derived-scopes.js +67 -0
- package/dist/utils/tap-store/derived-scopes.js.map +1 -0
- package/dist/utils/tap-store/index.d.ts +1 -0
- package/dist/utils/tap-store/index.d.ts.map +1 -1
- package/dist/utils/tap-store/index.js +4 -0
- package/dist/utils/tap-store/index.js.map +1 -1
- package/dist/utils/tap-store/tap-api.js +1 -1
- package/dist/utils/tap-store/tap-api.js.map +1 -1
- package/package.json +9 -9
- package/src/client/AssistantClient.ts +64 -38
- package/src/client/ModelContext.ts +28 -0
- package/src/client/ModelContextClient.ts +16 -0
- package/src/client/ToolUIClient.ts +50 -3
- package/src/client/ToolUIContext.ts +22 -0
- package/src/client/Tools.ts +68 -0
- package/src/client/types/ModelContext.ts +15 -0
- package/src/client/types/ThreadList.ts +4 -0
- package/src/client/types/ToolUI.ts +10 -1
- package/src/client/types/Tools.ts +11 -0
- package/src/context/providers/AttachmentByIndexProvider.tsx +21 -25
- package/src/context/providers/MessageByIndexProvider.tsx +31 -33
- package/src/context/providers/MessageProvider.tsx +12 -14
- package/src/context/providers/PartByIndexProvider.tsx +12 -14
- package/src/context/providers/TextMessagePartProvider.tsx +12 -14
- package/src/context/providers/ThreadListItemProvider.tsx +42 -46
- package/src/context/react/AssistantApiContext.tsx +69 -29
- package/src/context/react/index.ts +5 -1
- package/src/legacy-runtime/AssistantRuntimeProvider.tsx +7 -9
- package/src/legacy-runtime/RuntimeAdapter.ts +19 -0
- package/src/legacy-runtime/client/ThreadListRuntimeClient.ts +10 -1
- package/src/legacy-runtime/hooks/AssistantContext.ts +16 -2
- package/src/legacy-runtime/hooks/AttachmentContext.ts +6 -0
- package/src/legacy-runtime/hooks/ComposerContext.ts +41 -2
- package/src/legacy-runtime/hooks/MessageContext.ts +37 -2
- package/src/legacy-runtime/hooks/MessagePartContext.ts +6 -0
- package/src/legacy-runtime/hooks/ThreadContext.ts +27 -1
- package/src/legacy-runtime/hooks/ThreadListItemContext.ts +6 -0
- package/src/legacy-runtime/runtime-cores/core/AssistantRuntimeCore.tsx +1 -0
- package/src/legacy-runtime/runtime-cores/core/BaseAssistantRuntimeCore.tsx +4 -0
- package/src/legacy-runtime/runtime-cores/external-store/ExternalStoreThreadListRuntimeCore.tsx +4 -2
- package/src/legacy-runtime/runtime-cores/external-store/ExternalStoreThreadRuntimeCore.tsx +7 -1
- package/src/legacy-runtime/runtime-cores/external-store/auto-status.tsx +49 -16
- package/src/legacy-runtime/runtime-cores/external-store/external-message-converter.tsx +4 -0
- package/src/legacy-runtime/runtime-cores/local/LocalThreadListRuntimeCore.tsx +4 -2
- package/src/legacy-runtime/runtime-cores/utils/MessageRepository.tsx +1 -1
- package/src/model-context/index.ts +9 -0
- package/src/model-context/makeAssistantVisible.tsx +1 -1
- package/src/model-context/toolbox.tsx +37 -0
- package/src/model-context/useAssistantInstructions.tsx +1 -1
- package/src/model-context/useAssistantTool.tsx +1 -1
- package/src/primitives/index.ts +1 -0
- package/src/primitives/message/MessageParts.tsx +114 -32
- package/src/primitives/message/MessagePartsGrouped.tsx +3 -2
- package/src/primitives/reasoning/index.ts +1 -0
- package/src/primitives/reasoning/useScrollLock.tsx +86 -0
- package/src/types/MessagePartComponentTypes.tsx +7 -1
- package/src/types/index.ts +2 -0
- package/src/utils/tap-store/derived-scopes.ts +185 -0
- package/src/utils/tap-store/index.ts +9 -0
- package/src/utils/tap-store/tap-api.ts +1 -1
|
@@ -1,34 +1,67 @@
|
|
|
1
|
+
import { ReadonlyJSONValue } from "assistant-stream/utils";
|
|
1
2
|
import { MessageStatus } from "../../../types";
|
|
2
3
|
|
|
3
|
-
const
|
|
4
|
-
const AUTO_STATUS_COMPLETE = Object.freeze({
|
|
5
|
-
type: "complete",
|
|
6
|
-
reason: "unknown",
|
|
7
|
-
});
|
|
4
|
+
const symbolAutoStatus = Symbol("autoStatus");
|
|
8
5
|
|
|
9
|
-
const
|
|
10
|
-
type: "
|
|
11
|
-
|
|
12
|
-
|
|
6
|
+
const AUTO_STATUS_RUNNING = Object.freeze(
|
|
7
|
+
Object.assign({ type: "running" as const }, { [symbolAutoStatus]: true }),
|
|
8
|
+
);
|
|
9
|
+
const AUTO_STATUS_COMPLETE = Object.freeze(
|
|
10
|
+
Object.assign(
|
|
11
|
+
{
|
|
12
|
+
type: "complete" as const,
|
|
13
|
+
reason: "unknown" as const,
|
|
14
|
+
},
|
|
15
|
+
{ [symbolAutoStatus]: true },
|
|
16
|
+
),
|
|
17
|
+
);
|
|
13
18
|
|
|
14
|
-
const
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
19
|
+
const AUTO_STATUS_PENDING = Object.freeze(
|
|
20
|
+
Object.assign(
|
|
21
|
+
{
|
|
22
|
+
type: "requires-action" as const,
|
|
23
|
+
reason: "tool-calls" as const,
|
|
24
|
+
},
|
|
25
|
+
{ [symbolAutoStatus]: true },
|
|
26
|
+
),
|
|
27
|
+
);
|
|
28
|
+
|
|
29
|
+
const AUTO_STATUS_INTERRUPT = Object.freeze(
|
|
30
|
+
Object.assign(
|
|
31
|
+
{
|
|
32
|
+
type: "requires-action" as const,
|
|
33
|
+
reason: "interrupt" as const,
|
|
34
|
+
},
|
|
35
|
+
{ [symbolAutoStatus]: true },
|
|
36
|
+
),
|
|
37
|
+
);
|
|
18
38
|
|
|
19
39
|
export const isAutoStatus = (status: MessageStatus) =>
|
|
20
|
-
status
|
|
40
|
+
(status as any)[symbolAutoStatus] === true;
|
|
21
41
|
|
|
22
42
|
export const getAutoStatus = (
|
|
23
43
|
isLast: boolean,
|
|
24
44
|
isRunning: boolean,
|
|
25
45
|
hasInterruptedToolCalls: boolean,
|
|
26
46
|
hasPendingToolCalls: boolean,
|
|
27
|
-
|
|
28
|
-
|
|
47
|
+
error?: ReadonlyJSONValue,
|
|
48
|
+
): MessageStatus => {
|
|
49
|
+
if (isLast && error) {
|
|
50
|
+
return Object.assign(
|
|
51
|
+
{
|
|
52
|
+
type: "incomplete" as const,
|
|
53
|
+
reason: "error" as const,
|
|
54
|
+
error: error,
|
|
55
|
+
},
|
|
56
|
+
{ [symbolAutoStatus]: true },
|
|
57
|
+
);
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
return isLast && isRunning
|
|
29
61
|
? AUTO_STATUS_RUNNING
|
|
30
62
|
: hasInterruptedToolCalls
|
|
31
63
|
? AUTO_STATUS_INTERRUPT
|
|
32
64
|
: hasPendingToolCalls
|
|
33
65
|
? AUTO_STATUS_PENDING
|
|
34
66
|
: AUTO_STATUS_COMPLETE;
|
|
67
|
+
};
|
|
@@ -10,6 +10,7 @@ import { fromThreadMessageLike, ThreadMessageLike } from "./ThreadMessageLike";
|
|
|
10
10
|
import { getAutoStatus, isAutoStatus } from "./auto-status";
|
|
11
11
|
import { ThreadMessage, ToolCallMessagePart } from "../../../types";
|
|
12
12
|
import { ToolExecutionStatus } from "../assistant-transport/useToolInvocations";
|
|
13
|
+
import { ReadonlyJSONValue } from "assistant-stream/utils";
|
|
13
14
|
|
|
14
15
|
export namespace useExternalMessageConverter {
|
|
15
16
|
export type Message =
|
|
@@ -30,6 +31,7 @@ export namespace useExternalMessageConverter {
|
|
|
30
31
|
|
|
31
32
|
export type Metadata = {
|
|
32
33
|
readonly toolStatuses?: Record<string, ToolExecutionStatus>;
|
|
34
|
+
readonly error?: ReadonlyJSONValue;
|
|
33
35
|
};
|
|
34
36
|
|
|
35
37
|
export type Callback<T> = (
|
|
@@ -263,6 +265,7 @@ export const convertExternalMessages = <T extends WeakKey>(
|
|
|
263
265
|
isRunning,
|
|
264
266
|
hasSuspendedToolCalls,
|
|
265
267
|
hasPendingToolCalls,
|
|
268
|
+
isLast ? metadata.error : undefined,
|
|
266
269
|
);
|
|
267
270
|
const newMessage = fromThreadMessageLike(
|
|
268
271
|
joined,
|
|
@@ -348,6 +351,7 @@ export const useExternalMessageConverter = <T extends WeakKey>({
|
|
|
348
351
|
isRunning,
|
|
349
352
|
hasSuspendedToolCalls,
|
|
350
353
|
hasPendingToolCalls,
|
|
354
|
+
isLast ? state.metadata.error : undefined,
|
|
351
355
|
);
|
|
352
356
|
|
|
353
357
|
if (
|
|
@@ -104,8 +104,10 @@ export class LocalThreadListRuntimeCore
|
|
|
104
104
|
throw new Error("Method not implemented.");
|
|
105
105
|
}
|
|
106
106
|
|
|
107
|
-
public initialize(
|
|
108
|
-
|
|
107
|
+
public initialize(
|
|
108
|
+
threadId: string,
|
|
109
|
+
): Promise<{ remoteId: string; externalId: string | undefined }> {
|
|
110
|
+
return Promise.resolve({ remoteId: threadId, externalId: undefined });
|
|
109
111
|
}
|
|
110
112
|
|
|
111
113
|
public generateTitle(): never {
|
|
@@ -19,5 +19,14 @@ export { tool } from "./tool";
|
|
|
19
19
|
|
|
20
20
|
export { makeAssistantVisible } from "./makeAssistantVisible";
|
|
21
21
|
|
|
22
|
+
export {
|
|
23
|
+
Toolkit,
|
|
24
|
+
type ToolDefinition,
|
|
25
|
+
type ToolkitFallback,
|
|
26
|
+
type ToolkitLayout,
|
|
27
|
+
} from "./toolbox";
|
|
28
|
+
|
|
29
|
+
export { Tools } from "../client/Tools";
|
|
30
|
+
|
|
22
31
|
export * from "./registry";
|
|
23
32
|
export * from "./frame";
|
|
@@ -76,7 +76,7 @@ export const makeAssistantVisible = <T extends ComponentType<any>>(
|
|
|
76
76
|
|
|
77
77
|
const { clickable, editable } = config ?? {};
|
|
78
78
|
useEffect(() => {
|
|
79
|
-
return api.
|
|
79
|
+
return api.modelContext().register({
|
|
80
80
|
getModelContext: () => {
|
|
81
81
|
return {
|
|
82
82
|
tools: {
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
import type { ComponentType, ReactNode } from "react";
|
|
4
|
+
import type { Tool } from "assistant-stream";
|
|
5
|
+
import type { ToolCallMessagePartComponent } from "../types/MessagePartComponentTypes";
|
|
6
|
+
|
|
7
|
+
export type ToolDefinition<
|
|
8
|
+
TArgs extends Record<string, unknown>,
|
|
9
|
+
TResult,
|
|
10
|
+
> = Tool<TArgs, TResult> & {
|
|
11
|
+
render?: ToolCallMessagePartComponent<TArgs, TResult> | undefined;
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
export const FallbackSymbol = Symbol("Toolkit.Fallback");
|
|
15
|
+
export const LayoutSymbol = Symbol("Toolkit.Layout");
|
|
16
|
+
|
|
17
|
+
export type ToolkitFallback = {
|
|
18
|
+
render: ToolCallMessagePartComponent<unknown, unknown>;
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
export type ToolkitLayout = {
|
|
22
|
+
render: ComponentType<{ children: ReactNode }>;
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
export type Toolkit = Record<string, ToolDefinition<any, any>> & {
|
|
26
|
+
[FallbackSymbol]?: ToolkitFallback;
|
|
27
|
+
[LayoutSymbol]?: ToolkitLayout;
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
export const Toolkit = {
|
|
31
|
+
Fallback: FallbackSymbol,
|
|
32
|
+
Layout: LayoutSymbol,
|
|
33
|
+
} as const;
|
|
34
|
+
|
|
35
|
+
export type ToolsConfig = {
|
|
36
|
+
toolkit: Toolkit;
|
|
37
|
+
};
|
package/src/primitives/index.ts
CHANGED
|
@@ -16,3 +16,4 @@ export { useMessagePartSource } from "./messagePart/useMessagePartSource";
|
|
|
16
16
|
export { useMessagePartFile } from "./messagePart/useMessagePartFile";
|
|
17
17
|
export { useMessagePartImage } from "./messagePart/useMessagePartImage";
|
|
18
18
|
export { useThreadViewportAutoScroll } from "./thread/useThreadViewportAutoScroll";
|
|
19
|
+
export { useScrollLock } from "./reasoning";
|
|
@@ -25,6 +25,7 @@ import type {
|
|
|
25
25
|
ToolCallMessagePartProps,
|
|
26
26
|
FileMessagePartComponent,
|
|
27
27
|
ReasoningMessagePartComponent,
|
|
28
|
+
ReasoningGroupComponent,
|
|
28
29
|
} from "../../types/MessagePartComponentTypes";
|
|
29
30
|
import { MessagePartPrimitiveInProgress } from "../messagePart/MessagePartInProgress";
|
|
30
31
|
import { MessagePartStatus } from "../../types/AssistantTypes";
|
|
@@ -32,50 +33,75 @@ import { useShallow } from "zustand/shallow";
|
|
|
32
33
|
|
|
33
34
|
type MessagePartRange =
|
|
34
35
|
| { type: "single"; index: number }
|
|
35
|
-
| { type: "toolGroup"; startIndex: number; endIndex: number }
|
|
36
|
+
| { type: "toolGroup"; startIndex: number; endIndex: number }
|
|
37
|
+
| { type: "reasoningGroup"; startIndex: number; endIndex: number };
|
|
36
38
|
|
|
37
39
|
/**
|
|
38
|
-
*
|
|
39
|
-
*
|
|
40
|
+
* Creates a group state manager for a specific part type.
|
|
41
|
+
* Returns functions to start, end, and finalize groups.
|
|
42
|
+
*/
|
|
43
|
+
const createGroupState = <T extends "toolGroup" | "reasoningGroup">(
|
|
44
|
+
groupType: T,
|
|
45
|
+
) => {
|
|
46
|
+
let start = -1;
|
|
47
|
+
|
|
48
|
+
return {
|
|
49
|
+
startGroup: (index: number) => {
|
|
50
|
+
if (start === -1) {
|
|
51
|
+
start = index;
|
|
52
|
+
}
|
|
53
|
+
},
|
|
54
|
+
endGroup: (endIndex: number, ranges: MessagePartRange[]) => {
|
|
55
|
+
if (start !== -1) {
|
|
56
|
+
ranges.push({
|
|
57
|
+
type: groupType,
|
|
58
|
+
startIndex: start,
|
|
59
|
+
endIndex,
|
|
60
|
+
} as MessagePartRange);
|
|
61
|
+
start = -1;
|
|
62
|
+
}
|
|
63
|
+
},
|
|
64
|
+
finalize: (endIndex: number, ranges: MessagePartRange[]) => {
|
|
65
|
+
if (start !== -1) {
|
|
66
|
+
ranges.push({
|
|
67
|
+
type: groupType,
|
|
68
|
+
startIndex: start,
|
|
69
|
+
endIndex,
|
|
70
|
+
} as MessagePartRange);
|
|
71
|
+
}
|
|
72
|
+
},
|
|
73
|
+
};
|
|
74
|
+
};
|
|
75
|
+
|
|
76
|
+
/**
|
|
77
|
+
* Groups consecutive tool-call and reasoning message parts into ranges.
|
|
78
|
+
* Always groups tool calls and reasoning parts, even if there's only one.
|
|
40
79
|
*/
|
|
41
80
|
const groupMessageParts = (
|
|
42
81
|
messageTypes: readonly string[],
|
|
43
82
|
): MessagePartRange[] => {
|
|
44
83
|
const ranges: MessagePartRange[] = [];
|
|
45
|
-
|
|
84
|
+
const toolGroup = createGroupState("toolGroup");
|
|
85
|
+
const reasoningGroup = createGroupState("reasoningGroup");
|
|
46
86
|
|
|
47
87
|
for (let i = 0; i < messageTypes.length; i++) {
|
|
48
88
|
const type = messageTypes[i];
|
|
49
89
|
|
|
50
90
|
if (type === "tool-call") {
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
91
|
+
reasoningGroup.endGroup(i - 1, ranges);
|
|
92
|
+
toolGroup.startGroup(i);
|
|
93
|
+
} else if (type === "reasoning") {
|
|
94
|
+
toolGroup.endGroup(i - 1, ranges);
|
|
95
|
+
reasoningGroup.startGroup(i);
|
|
55
96
|
} else {
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
ranges.push({
|
|
59
|
-
type: "toolGroup",
|
|
60
|
-
startIndex: currentToolGroupStart,
|
|
61
|
-
endIndex: i - 1,
|
|
62
|
-
});
|
|
63
|
-
currentToolGroupStart = -1;
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
// Add non-tool-call part individually
|
|
97
|
+
toolGroup.endGroup(i - 1, ranges);
|
|
98
|
+
reasoningGroup.endGroup(i - 1, ranges);
|
|
67
99
|
ranges.push({ type: "single", index: i });
|
|
68
100
|
}
|
|
69
101
|
}
|
|
70
102
|
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
ranges.push({
|
|
74
|
-
type: "toolGroup",
|
|
75
|
-
startIndex: currentToolGroupStart,
|
|
76
|
-
endIndex: messageTypes.length - 1,
|
|
77
|
-
});
|
|
78
|
-
}
|
|
103
|
+
toolGroup.finalize(messageTypes.length - 1, ranges);
|
|
104
|
+
reasoningGroup.finalize(messageTypes.length - 1, ranges);
|
|
79
105
|
|
|
80
106
|
return ranges;
|
|
81
107
|
};
|
|
@@ -184,6 +210,37 @@ export namespace MessagePrimitiveParts {
|
|
|
184
210
|
ToolGroup?: ComponentType<
|
|
185
211
|
PropsWithChildren<{ startIndex: number; endIndex: number }>
|
|
186
212
|
>;
|
|
213
|
+
|
|
214
|
+
/**
|
|
215
|
+
* Component for rendering grouped reasoning parts.
|
|
216
|
+
*
|
|
217
|
+
* When provided, this component will automatically wrap reasoning message parts
|
|
218
|
+
* (one or more consecutive) in a group container. Each reasoning part inside
|
|
219
|
+
* renders its own text independently - no text merging occurs.
|
|
220
|
+
*
|
|
221
|
+
* The component receives:
|
|
222
|
+
* - `startIndex`: The index of the first reasoning part in the group
|
|
223
|
+
* - `endIndex`: The index of the last reasoning part in the group
|
|
224
|
+
* - `children`: The rendered Reasoning components (one per part)
|
|
225
|
+
*
|
|
226
|
+
* @example
|
|
227
|
+
* ```tsx
|
|
228
|
+
* // Collapsible reasoning group
|
|
229
|
+
* ReasoningGroup: ({ children }) => (
|
|
230
|
+
* <details className="reasoning-group">
|
|
231
|
+
* <summary>Reasoning</summary>
|
|
232
|
+
* <div className="reasoning-content">
|
|
233
|
+
* {children}
|
|
234
|
+
* </div>
|
|
235
|
+
* </details>
|
|
236
|
+
* )
|
|
237
|
+
* ```
|
|
238
|
+
*
|
|
239
|
+
* @param startIndex - Index of the first reasoning part in the group
|
|
240
|
+
* @param endIndex - Index of the last reasoning part in the group
|
|
241
|
+
* @param children - Rendered reasoning part components
|
|
242
|
+
*/
|
|
243
|
+
ReasoningGroup?: ReasoningGroupComponent;
|
|
187
244
|
}
|
|
188
245
|
| undefined;
|
|
189
246
|
};
|
|
@@ -196,8 +253,9 @@ const ToolUIDisplay = ({
|
|
|
196
253
|
Fallback: ToolCallMessagePartComponent | undefined;
|
|
197
254
|
} & ToolCallMessagePartProps) => {
|
|
198
255
|
const Render = useAssistantState(({ toolUIs }) => {
|
|
199
|
-
const Render =
|
|
200
|
-
|
|
256
|
+
const Render =
|
|
257
|
+
toolUIs.tools[props.toolName] ?? toolUIs.fallback ?? Fallback;
|
|
258
|
+
if (Array.isArray(Render)) return Render[0] ?? Fallback;
|
|
201
259
|
return Render;
|
|
202
260
|
});
|
|
203
261
|
if (!Render) return null;
|
|
@@ -219,6 +277,7 @@ const defaultComponents = {
|
|
|
219
277
|
File: () => null,
|
|
220
278
|
Unstable_Audio: () => null,
|
|
221
279
|
ToolGroup: ({ children }) => children,
|
|
280
|
+
ReasoningGroup: ({ children }) => children,
|
|
222
281
|
} satisfies MessagePrimitiveParts.Props["components"];
|
|
223
282
|
|
|
224
283
|
type MessagePartComponentProps = {
|
|
@@ -327,7 +386,8 @@ export const MessagePrimitivePartByIndex: FC<MessagePrimitivePartByIndex.Props>
|
|
|
327
386
|
prev.components?.File === next.components?.File &&
|
|
328
387
|
prev.components?.Unstable_Audio === next.components?.Unstable_Audio &&
|
|
329
388
|
prev.components?.tools === next.components?.tools &&
|
|
330
|
-
prev.components?.ToolGroup === next.components?.ToolGroup
|
|
389
|
+
prev.components?.ToolGroup === next.components?.ToolGroup &&
|
|
390
|
+
prev.components?.ReasoningGroup === next.components?.ReasoningGroup,
|
|
331
391
|
);
|
|
332
392
|
|
|
333
393
|
MessagePrimitivePartByIndex.displayName = "MessagePrimitive.PartByIndex";
|
|
@@ -415,12 +475,12 @@ export const MessagePrimitiveParts: FC<MessagePrimitiveParts.Props> = ({
|
|
|
415
475
|
components={components}
|
|
416
476
|
/>
|
|
417
477
|
);
|
|
418
|
-
} else {
|
|
478
|
+
} else if (range.type === "toolGroup") {
|
|
419
479
|
const ToolGroupComponent =
|
|
420
480
|
components!.ToolGroup ?? defaultComponents.ToolGroup;
|
|
421
481
|
return (
|
|
422
482
|
<ToolGroupComponent
|
|
423
|
-
key={range.startIndex}
|
|
483
|
+
key={`tool-${range.startIndex}`}
|
|
424
484
|
startIndex={range.startIndex}
|
|
425
485
|
endIndex={range.endIndex}
|
|
426
486
|
>
|
|
@@ -436,6 +496,28 @@ export const MessagePrimitiveParts: FC<MessagePrimitiveParts.Props> = ({
|
|
|
436
496
|
)}
|
|
437
497
|
</ToolGroupComponent>
|
|
438
498
|
);
|
|
499
|
+
} else {
|
|
500
|
+
// reasoningGroup
|
|
501
|
+
const ReasoningGroupComponent =
|
|
502
|
+
components!.ReasoningGroup ?? defaultComponents.ReasoningGroup;
|
|
503
|
+
return (
|
|
504
|
+
<ReasoningGroupComponent
|
|
505
|
+
key={`reasoning-${range.startIndex}`}
|
|
506
|
+
startIndex={range.startIndex}
|
|
507
|
+
endIndex={range.endIndex}
|
|
508
|
+
>
|
|
509
|
+
{Array.from(
|
|
510
|
+
{ length: range.endIndex - range.startIndex + 1 },
|
|
511
|
+
(_, i) => (
|
|
512
|
+
<MessagePrimitivePartByIndex
|
|
513
|
+
key={i}
|
|
514
|
+
index={range.startIndex + i}
|
|
515
|
+
components={components}
|
|
516
|
+
/>
|
|
517
|
+
),
|
|
518
|
+
)}
|
|
519
|
+
</ReasoningGroupComponent>
|
|
520
|
+
);
|
|
439
521
|
}
|
|
440
522
|
});
|
|
441
523
|
}, [messageRanges, components, contentLength]);
|
|
@@ -221,8 +221,9 @@ const ToolUIDisplay = ({
|
|
|
221
221
|
Fallback: ToolCallMessagePartComponent | undefined;
|
|
222
222
|
} & ToolCallMessagePartProps) => {
|
|
223
223
|
const Render = useAssistantState(({ toolUIs }) => {
|
|
224
|
-
const Render =
|
|
225
|
-
|
|
224
|
+
const Render =
|
|
225
|
+
toolUIs.tools[props.toolName] ?? toolUIs.fallback ?? Fallback;
|
|
226
|
+
if (Array.isArray(Render)) return Render[0] ?? Fallback;
|
|
226
227
|
return Render;
|
|
227
228
|
});
|
|
228
229
|
if (!Render) return null;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { useScrollLock } from "./useScrollLock";
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
import { type RefObject, useCallback, useEffect, useRef } from "react";
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Locks scroll position during collapsible/height animations and hides scrollbar.
|
|
7
|
+
*
|
|
8
|
+
* This utility prevents page jumps when content height changes during animations,
|
|
9
|
+
* providing a smooth user experience. It finds the nearest scrollable ancestor and
|
|
10
|
+
* temporarily locks its scroll position while the animation completes.
|
|
11
|
+
*
|
|
12
|
+
* - Prevents forced reflows: no layout reads, mutations scoped to scrollable parent only
|
|
13
|
+
* - Reactive: only intercepts scroll events when browser actually adjusts
|
|
14
|
+
* - Cleans up automatically after animation duration
|
|
15
|
+
*
|
|
16
|
+
* @param animatedElementRef - Ref to the animated element
|
|
17
|
+
* @param animationDuration - Lock duration in milliseconds
|
|
18
|
+
* @returns Function to activate the scroll lock
|
|
19
|
+
*
|
|
20
|
+
* @example
|
|
21
|
+
* ```tsx
|
|
22
|
+
* const collapsibleRef = useRef<HTMLDivElement>(null);
|
|
23
|
+
* const lockScroll = useScrollLock(collapsibleRef, 200);
|
|
24
|
+
*
|
|
25
|
+
* const handleCollapse = () => {
|
|
26
|
+
* lockScroll(); // Lock scroll before collapsing
|
|
27
|
+
* setIsOpen(false);
|
|
28
|
+
* };
|
|
29
|
+
* ```
|
|
30
|
+
*/
|
|
31
|
+
export const useScrollLock = <T extends HTMLElement = HTMLElement>(
|
|
32
|
+
animatedElementRef: RefObject<T | null>,
|
|
33
|
+
animationDuration: number,
|
|
34
|
+
) => {
|
|
35
|
+
const scrollContainerRef = useRef<HTMLElement | null>(null);
|
|
36
|
+
const cleanupRef = useRef<(() => void) | null>(null);
|
|
37
|
+
|
|
38
|
+
useEffect(() => {
|
|
39
|
+
return () => {
|
|
40
|
+
cleanupRef.current?.();
|
|
41
|
+
};
|
|
42
|
+
}, []);
|
|
43
|
+
|
|
44
|
+
const lockScroll = useCallback(() => {
|
|
45
|
+
cleanupRef.current?.();
|
|
46
|
+
|
|
47
|
+
(function findScrollableAncestor() {
|
|
48
|
+
if (scrollContainerRef.current || !animatedElementRef.current) return;
|
|
49
|
+
|
|
50
|
+
let el: HTMLElement | null = animatedElementRef.current;
|
|
51
|
+
while (el) {
|
|
52
|
+
const { overflowY } = getComputedStyle(el);
|
|
53
|
+
if (overflowY === "scroll" || overflowY === "auto") {
|
|
54
|
+
scrollContainerRef.current = el;
|
|
55
|
+
break;
|
|
56
|
+
}
|
|
57
|
+
el = el.parentElement;
|
|
58
|
+
}
|
|
59
|
+
})();
|
|
60
|
+
|
|
61
|
+
const scrollContainer = scrollContainerRef.current;
|
|
62
|
+
if (!scrollContainer) return;
|
|
63
|
+
|
|
64
|
+
const scrollPosition = scrollContainer.scrollTop;
|
|
65
|
+
const scrollbarWidth = scrollContainer.style.scrollbarWidth;
|
|
66
|
+
|
|
67
|
+
scrollContainer.style.scrollbarWidth = "none";
|
|
68
|
+
|
|
69
|
+
const resetPosition = () => (scrollContainer.scrollTop = scrollPosition);
|
|
70
|
+
scrollContainer.addEventListener("scroll", resetPosition);
|
|
71
|
+
|
|
72
|
+
const timeoutId = setTimeout(() => {
|
|
73
|
+
scrollContainer.removeEventListener("scroll", resetPosition);
|
|
74
|
+
scrollContainer.style.scrollbarWidth = scrollbarWidth;
|
|
75
|
+
cleanupRef.current = null;
|
|
76
|
+
}, animationDuration);
|
|
77
|
+
|
|
78
|
+
cleanupRef.current = () => {
|
|
79
|
+
clearTimeout(timeoutId);
|
|
80
|
+
scrollContainer.removeEventListener("scroll", resetPosition);
|
|
81
|
+
scrollContainer.style.scrollbarWidth = scrollbarWidth;
|
|
82
|
+
};
|
|
83
|
+
}, [animationDuration, animatedElementRef]);
|
|
84
|
+
|
|
85
|
+
return lockScroll;
|
|
86
|
+
};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { ComponentType } from "react";
|
|
1
|
+
import type { ComponentType, PropsWithChildren } from "react";
|
|
2
2
|
import type {
|
|
3
3
|
MessagePartStatus,
|
|
4
4
|
FileMessagePart,
|
|
@@ -24,6 +24,12 @@ export type ReasoningMessagePartProps = MessagePartState & ReasoningMessagePart;
|
|
|
24
24
|
export type ReasoningMessagePartComponent =
|
|
25
25
|
ComponentType<ReasoningMessagePartProps>;
|
|
26
26
|
|
|
27
|
+
export type ReasoningGroupProps = PropsWithChildren<{
|
|
28
|
+
startIndex: number;
|
|
29
|
+
endIndex: number;
|
|
30
|
+
}>;
|
|
31
|
+
export type ReasoningGroupComponent = ComponentType<ReasoningGroupProps>;
|
|
32
|
+
|
|
27
33
|
export type SourceMessagePartProps = MessagePartState & SourceMessagePart;
|
|
28
34
|
export type SourceMessagePartComponent = ComponentType<SourceMessagePartProps>;
|
|
29
35
|
|
package/src/types/index.ts
CHANGED