@gram-ai/elements 1.27.3 → 1.27.5
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 +72 -60
- package/README.typedoc.md +6 -6
- package/bin/cli.js +74 -74
- package/dist/compat-shims-CO9JXXV4.cjs.map +1 -1
- package/dist/{compat-shims-BPJ7Q68c.js → compat-shims-DxtUrORi.js} +4 -2
- package/dist/compat-shims-DxtUrORi.js.map +1 -0
- package/dist/components/ShareButton/index.d.ts +2 -2
- package/dist/components/assistant-ui/message-feedback.d.ts +1 -1
- package/dist/components/assistant-ui/tooltip-icon-button.d.ts +2 -2
- package/dist/components/ui/avatar.d.ts +2 -2
- package/dist/components/ui/button.d.ts +1 -1
- package/dist/components/ui/calendar.d.ts +1 -1
- package/dist/components/ui/collapsible.d.ts +1 -1
- package/dist/components/ui/dialog.d.ts +4 -4
- package/dist/components/ui/popover.d.ts +2 -2
- package/dist/components/ui/skeleton.d.ts +1 -1
- package/dist/components/ui/time-range-picker.d.ts +4 -2
- package/dist/components/ui/tool-ui.d.ts +7 -7
- package/dist/components/ui/tooltip.d.ts +2 -2
- package/dist/contexts/ConnectionStatusContext.d.ts +1 -1
- package/dist/elements.cjs +1 -1
- package/dist/elements.css +1 -1
- package/dist/elements.js +2 -2
- package/dist/hooks/useDensity.d.ts +73 -73
- package/dist/hooks/useMCPTools.d.ts +1 -1
- package/dist/hooks/useRadius.d.ts +1 -1
- package/dist/{index-BpJstUh1.cjs → index-C4bFBGfl.cjs} +4 -4
- package/dist/{index-BpJstUh1.cjs.map → index-C4bFBGfl.cjs.map} +1 -1
- package/dist/{index-CUitXazZ.js → index-D93pV0_o.js} +55 -55
- package/dist/{index-CUitXazZ.js.map → index-D93pV0_o.js.map} +1 -1
- package/dist/{index-DBrhzauj.js → index-DuCQRbcQ.js} +6386 -6337
- package/dist/index-DuCQRbcQ.js.map +1 -0
- package/dist/{index-DxfW52oA.cjs → index-y_PNN5vK.cjs} +64 -46
- package/dist/index-y_PNN5vK.cjs.map +1 -0
- package/dist/lib/cassette.d.ts +4 -4
- package/dist/lib/errorTracking.d.ts +1 -1
- package/dist/lib/messageConverter.d.ts +1 -1
- package/dist/lib/models.d.ts +1 -1
- package/dist/plugins/chart/ui/bar-chart.d.ts +1 -1
- package/dist/plugins/generative-ui/ui/accordion-wrapper.d.ts +2 -2
- package/dist/plugins/generative-ui/ui/accordion.d.ts +1 -1
- package/dist/plugins/generative-ui/ui/action-button.d.ts +2 -2
- package/dist/plugins/generative-ui/ui/alert-wrapper.d.ts +1 -1
- package/dist/plugins/generative-ui/ui/alert.d.ts +4 -4
- package/dist/plugins/generative-ui/ui/avatar.d.ts +5 -5
- package/dist/plugins/generative-ui/ui/badge.d.ts +2 -2
- package/dist/plugins/generative-ui/ui/button-wrapper.d.ts +2 -2
- package/dist/plugins/generative-ui/ui/button.d.ts +2 -2
- package/dist/plugins/generative-ui/ui/card-wrapper.d.ts +2 -2
- package/dist/plugins/generative-ui/ui/card.d.ts +8 -8
- package/dist/plugins/generative-ui/ui/checkbox.d.ts +1 -1
- package/dist/plugins/generative-ui/ui/data-table.d.ts +2 -2
- package/dist/plugins/generative-ui/ui/dialog.d.ts +3 -3
- package/dist/plugins/generative-ui/ui/dropdown-menu.d.ts +3 -3
- package/dist/plugins/generative-ui/ui/grid.d.ts +3 -3
- package/dist/plugins/generative-ui/ui/input-wrapper.d.ts +1 -1
- package/dist/plugins/generative-ui/ui/input.d.ts +2 -2
- package/dist/plugins/generative-ui/ui/label.d.ts +1 -1
- package/dist/plugins/generative-ui/ui/metric.d.ts +3 -3
- package/dist/plugins/generative-ui/ui/pagination.d.ts +6 -6
- package/dist/plugins/generative-ui/ui/popover.d.ts +4 -4
- package/dist/plugins/generative-ui/ui/progress.d.ts +2 -2
- package/dist/plugins/generative-ui/ui/radio-group.d.ts +1 -1
- package/dist/plugins/generative-ui/ui/select.d.ts +2 -2
- package/dist/plugins/generative-ui/ui/separator.d.ts +1 -1
- package/dist/plugins/generative-ui/ui/skeleton.d.ts +1 -1
- package/dist/plugins/generative-ui/ui/stack.d.ts +6 -6
- package/dist/plugins/generative-ui/ui/switch.d.ts +2 -2
- package/dist/plugins/generative-ui/ui/table.d.ts +9 -9
- package/dist/plugins/generative-ui/ui/tabs-wrapper.d.ts +1 -1
- package/dist/plugins/generative-ui/ui/tabs.d.ts +1 -1
- package/dist/plugins/generative-ui/ui/text.d.ts +3 -3
- package/dist/plugins/generative-ui/ui/textarea.d.ts +2 -2
- package/dist/plugins/generative-ui/ui/tooltip.d.ts +1 -1
- package/dist/plugins.cjs +1 -1
- package/dist/plugins.js +1 -1
- package/dist/{profiler-D6ndqfsd.js → profiler-FpBY9eRv.js} +2 -2
- package/dist/{profiler-D6ndqfsd.js.map → profiler-FpBY9eRv.js.map} +1 -1
- package/dist/{profiler-DhnzZ34c.cjs → profiler-_mthyjvo.cjs} +2 -2
- package/dist/{profiler-DhnzZ34c.cjs.map → profiler-_mthyjvo.cjs.map} +1 -1
- package/dist/react-shim.js +1 -1
- package/dist/server/express.cjs.map +1 -1
- package/dist/server/express.js.map +1 -1
- package/dist/{startRecording-BwXmdmy1.cjs → startRecording-NJcpiHw-.cjs} +2 -2
- package/dist/{startRecording-BwXmdmy1.cjs.map → startRecording-NJcpiHw-.cjs.map} +1 -1
- package/dist/{startRecording-B_9CRZ_P.js → startRecording-r5MXQ2Dm.js} +2 -2
- package/dist/{startRecording-B_9CRZ_P.js.map → startRecording-r5MXQ2Dm.js.map} +1 -1
- package/dist/types/index.d.ts +2 -2
- package/package.json +1 -5
- package/src/compat-plugin.ts +14 -14
- package/src/compat-shims.ts +33 -31
- package/src/compat.test.ts +48 -48
- package/src/compat.ts +6 -6
- package/src/components/Chat/index.tsx +17 -17
- package/src/components/Chat/stories/Charts.stories.tsx +98 -98
- package/src/components/Chat/stories/Composer.stories.tsx +15 -15
- package/src/components/Chat/stories/ConnectionConfiguration.stories.tsx +44 -44
- package/src/components/Chat/stories/CustomComponents.stories.tsx +17 -17
- package/src/components/Chat/stories/Density.stories.tsx +20 -20
- package/src/components/Chat/stories/ErrorBoundary.stories.tsx +47 -47
- package/src/components/Chat/stories/FrontendTools.stories.tsx +39 -39
- package/src/components/Chat/stories/GenerativeUI.stories.tsx +48 -48
- package/src/components/Chat/stories/MessageFeedback.stories.tsx +52 -52
- package/src/components/Chat/stories/Modal.stories.tsx +28 -28
- package/src/components/Chat/stories/Model.stories.tsx +11 -11
- package/src/components/Chat/stories/Radius.stories.tsx +20 -20
- package/src/components/Chat/stories/Sidecar.stories.tsx +13 -13
- package/src/components/Chat/stories/StyleIsolation.stories.tsx +11 -11
- package/src/components/Chat/stories/Theme.stories.tsx +25 -25
- package/src/components/Chat/stories/Thread.stories.tsx +25 -25
- package/src/components/Chat/stories/ToolApproval.stories.tsx +55 -55
- package/src/components/Chat/stories/ToolMentions.stories.tsx +17 -17
- package/src/components/Chat/stories/Tools.stories.tsx +88 -88
- package/src/components/Chat/stories/Variants.stories.tsx +32 -32
- package/src/components/Chat/stories/Welcome.stories.tsx +14 -14
- package/src/components/ChatHistory.tsx +7 -7
- package/src/components/FrontendTools/index.tsx +5 -5
- package/src/components/Replay.stories.tsx +157 -157
- package/src/components/Replay.tsx +76 -73
- package/src/components/ShadowRoot.tsx +40 -40
- package/src/components/ShareButton/index.tsx +32 -32
- package/src/components/assistant-ui/assistant-modal.tsx +92 -87
- package/src/components/assistant-ui/assistant-sidecar.tsx +35 -35
- package/src/components/assistant-ui/attachment.tsx +80 -80
- package/src/components/assistant-ui/connection-status-indicator.tsx +33 -33
- package/src/components/assistant-ui/error-boundary.tsx +34 -34
- package/src/components/assistant-ui/follow-on-suggestions.tsx +26 -26
- package/src/components/assistant-ui/markdown-text.tsx +69 -69
- package/src/components/assistant-ui/mentioned-tools-badges.tsx +38 -38
- package/src/components/assistant-ui/message-feedback.tsx +74 -61
- package/src/components/assistant-ui/reasoning.tsx +83 -83
- package/src/components/assistant-ui/thread-list.tsx +45 -45
- package/src/components/assistant-ui/thread.tsx +278 -278
- package/src/components/assistant-ui/tool-fallback.tsx +37 -37
- package/src/components/assistant-ui/tool-group.tsx +26 -26
- package/src/components/assistant-ui/tool-mention-autocomplete.tsx +122 -122
- package/src/components/assistant-ui/tooltip-icon-button.tsx +18 -18
- package/src/components/ui/avatar.tsx +12 -12
- package/src/components/ui/button.tsx +12 -12
- package/src/components/ui/buttonVariants.ts +17 -17
- package/src/components/ui/calendar.tsx +106 -106
- package/src/components/ui/charts.stories.tsx +56 -56
- package/src/components/ui/collapsible.tsx +5 -5
- package/src/components/ui/dialog.tsx +30 -30
- package/src/components/ui/generative-ui.stories.tsx +200 -200
- package/src/components/ui/generative-ui.tsx +26 -26
- package/src/components/ui/popover.tsx +14 -14
- package/src/components/ui/skeleton.tsx +5 -5
- package/src/components/ui/time-range-picker.stories.tsx +80 -80
- package/src/components/ui/time-range-picker.tsx +272 -235
- package/src/components/ui/tool-ui.stories.tsx +37 -37
- package/src/components/ui/tool-ui.tsx +221 -215
- package/src/components/ui/tooltip.tsx +15 -15
- package/src/constants/tailwind.ts +1 -1
- package/src/contexts/ChatIdContext.tsx +7 -7
- package/src/contexts/ConnectionStatusContext.tsx +64 -64
- package/src/contexts/ElementsProvider.tsx +222 -211
- package/src/contexts/ReplayContext.ts +3 -3
- package/src/contexts/ToolApprovalContext.tsx +54 -54
- package/src/contexts/ToolExecutionContext.tsx +34 -34
- package/src/contexts/contexts.ts +7 -7
- package/src/contexts/portal-container-context.ts +2 -2
- package/src/contexts/portal-container.tsx +7 -7
- package/src/embedded.ts +1 -1
- package/src/global.css +25 -25
- package/src/hooks/useAuth.ts +72 -72
- package/src/hooks/useDensity.ts +79 -79
- package/src/hooks/useElements.ts +6 -6
- package/src/hooks/useExpanded.ts +12 -12
- package/src/hooks/useFollowOnSuggestions.ts +87 -82
- package/src/hooks/useGramThreadListAdapter.tsx +99 -99
- package/src/hooks/useMCPTools.ts +47 -47
- package/src/hooks/useModel.ts +14 -14
- package/src/hooks/usePluginComponents.ts +11 -11
- package/src/hooks/usePortalContainer.ts +5 -5
- package/src/hooks/useRadius.ts +23 -23
- package/src/hooks/useRecordCassette.ts +34 -34
- package/src/hooks/useSession.ts +11 -11
- package/src/hooks/useThemeProps.ts +13 -13
- package/src/hooks/useThreadId.ts +4 -4
- package/src/hooks/useToolApproval.ts +7 -7
- package/src/hooks/useToolMentions.ts +40 -40
- package/src/index.ts +26 -26
- package/src/lib/api.test.ts +61 -61
- package/src/lib/api.ts +4 -3
- package/src/lib/auth.ts +13 -13
- package/src/lib/cassette.ts +84 -84
- package/src/lib/easing.ts +1 -1
- package/src/lib/errorTracking.config.ts +5 -5
- package/src/lib/errorTracking.ts +29 -29
- package/src/lib/generative-ui.ts +7 -7
- package/src/lib/humanize.ts +3 -3
- package/src/lib/messageConverter.test.ts +130 -127
- package/src/lib/messageConverter.ts +196 -196
- package/src/lib/models.ts +21 -20
- package/src/lib/token.test.ts +56 -56
- package/src/lib/token.ts +14 -14
- package/src/lib/tool-mentions.ts +45 -45
- package/src/lib/tools.ts +66 -62
- package/src/lib/utils.ts +5 -5
- package/src/lib.d.ts +1 -1
- package/src/plugins/README.md +5 -5
- package/src/plugins/chart/catalog.ts +18 -18
- package/src/plugins/chart/chart.test.ts +31 -31
- package/src/plugins/chart/component.tsx +34 -34
- package/src/plugins/chart/index.ts +4 -4
- package/src/plugins/chart/ui/area-chart.tsx +42 -42
- package/src/plugins/chart/ui/bar-chart.tsx +46 -46
- package/src/plugins/chart/ui/donut-chart.tsx +48 -48
- package/src/plugins/chart/ui/index.ts +7 -7
- package/src/plugins/chart/ui/line-chart.tsx +43 -43
- package/src/plugins/chart/ui/pie-chart.tsx +44 -44
- package/src/plugins/chart/ui/radar-chart.tsx +33 -33
- package/src/plugins/chart/ui/scatter-chart.tsx +43 -43
- package/src/plugins/components/MacOSWindowFrame.tsx +15 -15
- package/src/plugins/components/PluginLoadingState.tsx +10 -10
- package/src/plugins/components/index.ts +1 -1
- package/src/plugins/generative-ui/catalog.ts +54 -54
- package/src/plugins/generative-ui/component.tsx +85 -85
- package/src/plugins/generative-ui/index.ts +4 -4
- package/src/plugins/generative-ui/ui/accordion-wrapper.tsx +16 -16
- package/src/plugins/generative-ui/ui/accordion.tsx +16 -16
- package/src/plugins/generative-ui/ui/action-button.tsx +28 -28
- package/src/plugins/generative-ui/ui/alert-wrapper.tsx +8 -8
- package/src/plugins/generative-ui/ui/alert.tsx +20 -20
- package/src/plugins/generative-ui/ui/avatar-wrapper.tsx +7 -7
- package/src/plugins/generative-ui/ui/avatar.tsx +30 -30
- package/src/plugins/generative-ui/ui/badge.tsx +22 -22
- package/src/plugins/generative-ui/ui/button-wrapper.tsx +12 -12
- package/src/plugins/generative-ui/ui/button.tsx +28 -28
- package/src/plugins/generative-ui/ui/card-wrapper.tsx +8 -8
- package/src/plugins/generative-ui/ui/card.tsx +27 -27
- package/src/plugins/generative-ui/ui/checkbox-wrapper.tsx +9 -9
- package/src/plugins/generative-ui/ui/checkbox.tsx +9 -9
- package/src/plugins/generative-ui/ui/data-table.tsx +8 -8
- package/src/plugins/generative-ui/ui/dialog.tsx +31 -31
- package/src/plugins/generative-ui/ui/dropdown-menu.tsx +44 -44
- package/src/plugins/generative-ui/ui/grid.tsx +12 -12
- package/src/plugins/generative-ui/ui/index.ts +40 -40
- package/src/plugins/generative-ui/ui/input-wrapper.tsx +11 -11
- package/src/plugins/generative-ui/ui/input.tsx +9 -9
- package/src/plugins/generative-ui/ui/label.tsx +8 -8
- package/src/plugins/generative-ui/ui/list.tsx +11 -11
- package/src/plugins/generative-ui/ui/metric.tsx +23 -23
- package/src/plugins/generative-ui/ui/pagination.tsx +28 -28
- package/src/plugins/generative-ui/ui/popover.tsx +21 -21
- package/src/plugins/generative-ui/ui/progress.tsx +13 -13
- package/src/plugins/generative-ui/ui/radio-group.tsx +12 -12
- package/src/plugins/generative-ui/ui/select-wrapper.tsx +7 -7
- package/src/plugins/generative-ui/ui/select.tsx +37 -37
- package/src/plugins/generative-ui/ui/separator.tsx +9 -9
- package/src/plugins/generative-ui/ui/skeleton-wrapper.tsx +10 -10
- package/src/plugins/generative-ui/ui/skeleton.tsx +5 -5
- package/src/plugins/generative-ui/ui/stack.tsx +28 -28
- package/src/plugins/generative-ui/ui/switch.tsx +11 -11
- package/src/plugins/generative-ui/ui/table.tsx +32 -32
- package/src/plugins/generative-ui/ui/tabs-wrapper.tsx +11 -11
- package/src/plugins/generative-ui/ui/tabs.tsx +26 -26
- package/src/plugins/generative-ui/ui/text.tsx +12 -12
- package/src/plugins/generative-ui/ui/textarea.tsx +7 -7
- package/src/plugins/generative-ui/ui/tooltip.tsx +12 -12
- package/src/plugins/index.ts +7 -7
- package/src/react-shim.ts +6 -6
- package/src/server/bun.ts +12 -12
- package/src/server/core.ts +25 -25
- package/src/server/express.ts +17 -15
- package/src/server/fastify.ts +14 -14
- package/src/server/hono.ts +9 -9
- package/src/server/nextjs.ts +12 -12
- package/src/server/tanstack-start.ts +12 -12
- package/src/server.ts +27 -27
- package/src/storybook.d.ts +4 -4
- package/src/types/index.ts +122 -122
- package/src/types/plugins.ts +7 -7
- package/src/vite-env.d.ts +12 -12
- package/dist/compat-shims-BPJ7Q68c.js.map +0 -1
- package/dist/index-DBrhzauj.js.map +0 -1
- package/dist/index-DxfW52oA.cjs.map +0 -1
|
@@ -5,14 +5,14 @@ import {
|
|
|
5
5
|
ThreadHistoryAdapter,
|
|
6
6
|
useAssistantApi,
|
|
7
7
|
type AssistantApi,
|
|
8
|
-
} from
|
|
9
|
-
import { createAssistantStream, type AssistantStream } from
|
|
8
|
+
} from "@assistant-ui/react";
|
|
9
|
+
import { createAssistantStream, type AssistantStream } from "assistant-stream";
|
|
10
10
|
import {
|
|
11
11
|
GramChatOverview,
|
|
12
12
|
GramChat,
|
|
13
13
|
convertGramMessagesToExported,
|
|
14
14
|
convertGramMessagesToUIMessages,
|
|
15
|
-
} from
|
|
15
|
+
} from "@/lib/messageConverter";
|
|
16
16
|
import {
|
|
17
17
|
useCallback,
|
|
18
18
|
useEffect,
|
|
@@ -20,32 +20,32 @@ import {
|
|
|
20
20
|
useRef,
|
|
21
21
|
useState,
|
|
22
22
|
type PropsWithChildren,
|
|
23
|
-
} from
|
|
23
|
+
} from "react";
|
|
24
24
|
|
|
25
25
|
/**
|
|
26
26
|
* Prefix used by assistant-ui for local thread IDs that haven't been persisted yet.
|
|
27
27
|
* This is an internal implementation detail of assistant-ui's RemoteThreadListThreadListRuntimeCore.
|
|
28
28
|
* If the library changes this prefix, we only need to update it here.
|
|
29
29
|
*/
|
|
30
|
-
const LOCAL_THREAD_ID_PREFIX =
|
|
30
|
+
const LOCAL_THREAD_ID_PREFIX = "__LOCALID_";
|
|
31
31
|
|
|
32
32
|
/**
|
|
33
33
|
* Checks if a thread ID is a local (unpersisted) thread ID.
|
|
34
34
|
* Local IDs are generated by assistant-ui before the thread is initialized with a remote ID.
|
|
35
35
|
*/
|
|
36
36
|
export function isLocalThreadId(threadId: string | null | undefined): boolean {
|
|
37
|
-
return !!threadId?.startsWith(LOCAL_THREAD_ID_PREFIX)
|
|
37
|
+
return !!threadId?.startsWith(LOCAL_THREAD_ID_PREFIX);
|
|
38
38
|
}
|
|
39
39
|
|
|
40
40
|
export interface ThreadListAdapterOptions {
|
|
41
|
-
apiUrl: string
|
|
42
|
-
headers: Record<string, string
|
|
41
|
+
apiUrl: string;
|
|
42
|
+
headers: Record<string, string>;
|
|
43
43
|
/** Map to translate local thread IDs to UUIDs (shared with transport) */
|
|
44
|
-
localIdToUuidMap?: Map<string, string
|
|
44
|
+
localIdToUuidMap?: Map<string, string>;
|
|
45
45
|
}
|
|
46
46
|
|
|
47
47
|
interface ListChatsResponse {
|
|
48
|
-
chats: GramChatOverview[]
|
|
48
|
+
chats: GramChatOverview[];
|
|
49
49
|
}
|
|
50
50
|
|
|
51
51
|
/**
|
|
@@ -54,42 +54,42 @@ interface ListChatsResponse {
|
|
|
54
54
|
* signature doesn't match our concrete implementation, but it works at runtime.
|
|
55
55
|
*/
|
|
56
56
|
class GramThreadHistoryAdapter {
|
|
57
|
-
private apiUrl: string
|
|
58
|
-
private headers: Record<string, string
|
|
59
|
-
private store: AssistantApi
|
|
57
|
+
private apiUrl: string;
|
|
58
|
+
private headers: Record<string, string>;
|
|
59
|
+
private store: AssistantApi;
|
|
60
60
|
|
|
61
61
|
constructor(
|
|
62
62
|
apiUrl: string,
|
|
63
63
|
headers: Record<string, string>,
|
|
64
|
-
store: AssistantApi
|
|
64
|
+
store: AssistantApi,
|
|
65
65
|
) {
|
|
66
|
-
this.apiUrl = apiUrl
|
|
67
|
-
this.headers = headers
|
|
68
|
-
this.store = store
|
|
66
|
+
this.apiUrl = apiUrl;
|
|
67
|
+
this.headers = headers;
|
|
68
|
+
this.store = store;
|
|
69
69
|
}
|
|
70
70
|
|
|
71
71
|
async load() {
|
|
72
|
-
const remoteId = this.store.threadListItem().getState().remoteId
|
|
72
|
+
const remoteId = this.store.threadListItem().getState().remoteId;
|
|
73
73
|
if (!remoteId) {
|
|
74
|
-
return { messages: [], headId: null }
|
|
74
|
+
return { messages: [], headId: null };
|
|
75
75
|
}
|
|
76
76
|
|
|
77
77
|
try {
|
|
78
78
|
const response = await fetch(
|
|
79
79
|
`${this.apiUrl}/rpc/chat.load?id=${encodeURIComponent(remoteId)}`,
|
|
80
|
-
{ headers: this.headers }
|
|
81
|
-
)
|
|
80
|
+
{ headers: this.headers },
|
|
81
|
+
);
|
|
82
82
|
|
|
83
83
|
if (!response.ok) {
|
|
84
|
-
console.error(
|
|
85
|
-
return { messages: [], headId: null }
|
|
84
|
+
console.error("Failed to load chat:", response.status);
|
|
85
|
+
return { messages: [], headId: null };
|
|
86
86
|
}
|
|
87
87
|
|
|
88
|
-
const chat = (await response.json()) as GramChat
|
|
89
|
-
return convertGramMessagesToExported(chat.messages)
|
|
88
|
+
const chat = (await response.json()) as GramChat;
|
|
89
|
+
return convertGramMessagesToExported(chat.messages);
|
|
90
90
|
} catch (error) {
|
|
91
|
-
console.error(
|
|
92
|
-
return { messages: [], headId: null }
|
|
91
|
+
console.error("Error loading chat:", error);
|
|
92
|
+
return { messages: [], headId: null };
|
|
93
93
|
}
|
|
94
94
|
}
|
|
95
95
|
|
|
@@ -104,23 +104,23 @@ class GramThreadHistoryAdapter {
|
|
|
104
104
|
withFormat(_formatAdapter: unknown) {
|
|
105
105
|
return {
|
|
106
106
|
load: async () => {
|
|
107
|
-
const remoteId = this.store.threadListItem().getState().remoteId
|
|
107
|
+
const remoteId = this.store.threadListItem().getState().remoteId;
|
|
108
108
|
if (!remoteId) {
|
|
109
|
-
return { messages: [], headId: null }
|
|
109
|
+
return { messages: [], headId: null };
|
|
110
110
|
}
|
|
111
111
|
|
|
112
112
|
const response = await fetch(
|
|
113
113
|
`${this.apiUrl}/rpc/chat.load?id=${encodeURIComponent(remoteId)}`,
|
|
114
|
-
{ headers: this.headers }
|
|
115
|
-
)
|
|
114
|
+
{ headers: this.headers },
|
|
115
|
+
);
|
|
116
116
|
|
|
117
117
|
if (!response.ok) {
|
|
118
|
-
console.error(
|
|
119
|
-
return { messages: [], headId: null }
|
|
118
|
+
console.error("Failed to load chat (withFormat):", response.status);
|
|
119
|
+
return { messages: [], headId: null };
|
|
120
120
|
}
|
|
121
121
|
|
|
122
|
-
const chat = (await response.json()) as GramChat
|
|
123
|
-
return convertGramMessagesToUIMessages(chat.messages)
|
|
122
|
+
const chat = (await response.json()) as GramChat;
|
|
123
|
+
return convertGramMessagesToUIMessages(chat.messages);
|
|
124
124
|
|
|
125
125
|
// // Filter out system messages (assistant-ui doesn't support them in the import path)
|
|
126
126
|
// const filteredMessages = chat.messages.filter(
|
|
@@ -158,7 +158,7 @@ class GramThreadHistoryAdapter {
|
|
|
158
158
|
append: async () => {
|
|
159
159
|
// No-op
|
|
160
160
|
},
|
|
161
|
-
}
|
|
161
|
+
};
|
|
162
162
|
}
|
|
163
163
|
}
|
|
164
164
|
|
|
@@ -166,19 +166,19 @@ class GramThreadHistoryAdapter {
|
|
|
166
166
|
* Hook to create a Gram thread history adapter.
|
|
167
167
|
*/
|
|
168
168
|
function useGramThreadHistoryAdapter(
|
|
169
|
-
optionsRef: React.RefObject<ThreadListAdapterOptions
|
|
169
|
+
optionsRef: React.RefObject<ThreadListAdapterOptions>,
|
|
170
170
|
): ThreadHistoryAdapter {
|
|
171
|
-
const store = useAssistantApi()
|
|
171
|
+
const store = useAssistantApi();
|
|
172
172
|
const [adapter] = useState(
|
|
173
173
|
() =>
|
|
174
174
|
new GramThreadHistoryAdapter(
|
|
175
175
|
optionsRef.current.apiUrl,
|
|
176
176
|
optionsRef.current.headers,
|
|
177
|
-
store
|
|
178
|
-
)
|
|
179
|
-
)
|
|
177
|
+
store,
|
|
178
|
+
),
|
|
179
|
+
);
|
|
180
180
|
// Cast to ThreadHistoryAdapter - the withFormat generic doesn't match but works at runtime
|
|
181
|
-
return adapter as unknown as ThreadHistoryAdapter
|
|
181
|
+
return adapter as unknown as ThreadHistoryAdapter;
|
|
182
182
|
}
|
|
183
183
|
|
|
184
184
|
/**
|
|
@@ -186,25 +186,25 @@ function useGramThreadHistoryAdapter(
|
|
|
186
186
|
* This properly handles React component identity for the Provider.
|
|
187
187
|
*/
|
|
188
188
|
export function useGramThreadListAdapter(
|
|
189
|
-
options: ThreadListAdapterOptions
|
|
189
|
+
options: ThreadListAdapterOptions,
|
|
190
190
|
): RemoteThreadListAdapter {
|
|
191
|
-
const optionsRef = useRef(options)
|
|
191
|
+
const optionsRef = useRef(options);
|
|
192
192
|
useEffect(() => {
|
|
193
|
-
optionsRef.current = options
|
|
194
|
-
}, [options])
|
|
193
|
+
optionsRef.current = options;
|
|
194
|
+
}, [options]);
|
|
195
195
|
|
|
196
196
|
// Create stable Provider component using useCallback
|
|
197
197
|
const unstable_Provider = useCallback(function GramHistoryProvider({
|
|
198
198
|
children,
|
|
199
199
|
}: PropsWithChildren) {
|
|
200
|
-
const history = useGramThreadHistoryAdapter(optionsRef)
|
|
201
|
-
const adapters = useMemo(() => ({ history }), [history])
|
|
200
|
+
const history = useGramThreadHistoryAdapter(optionsRef);
|
|
201
|
+
const adapters = useMemo(() => ({ history }), [history]);
|
|
202
202
|
return (
|
|
203
203
|
<RuntimeAdapterProvider adapters={adapters}>
|
|
204
204
|
{children}
|
|
205
205
|
</RuntimeAdapterProvider>
|
|
206
|
-
)
|
|
207
|
-
}, [])
|
|
206
|
+
);
|
|
207
|
+
}, []);
|
|
208
208
|
|
|
209
209
|
// Return adapter with stable methods
|
|
210
210
|
return useMemo(
|
|
@@ -217,26 +217,26 @@ export function useGramThreadListAdapter(
|
|
|
217
217
|
`${optionsRef.current.apiUrl}/rpc/chat.list`,
|
|
218
218
|
{
|
|
219
219
|
headers: optionsRef.current.headers,
|
|
220
|
-
}
|
|
221
|
-
)
|
|
220
|
+
},
|
|
221
|
+
);
|
|
222
222
|
|
|
223
223
|
if (!response.ok) {
|
|
224
|
-
console.error(
|
|
225
|
-
return { threads: [] }
|
|
224
|
+
console.error("Failed to list chats:", response.status);
|
|
225
|
+
return { threads: [] };
|
|
226
226
|
}
|
|
227
227
|
|
|
228
|
-
const data = (await response.json()) as ListChatsResponse
|
|
228
|
+
const data = (await response.json()) as ListChatsResponse;
|
|
229
229
|
return {
|
|
230
230
|
threads: data.chats.map((chat) => ({
|
|
231
231
|
remoteId: chat.id,
|
|
232
232
|
externalId: chat.id,
|
|
233
|
-
status:
|
|
234
|
-
title: chat.title ||
|
|
233
|
+
status: "regular" as const,
|
|
234
|
+
title: chat.title || "New Chat",
|
|
235
235
|
})),
|
|
236
|
-
}
|
|
236
|
+
};
|
|
237
237
|
} catch (error) {
|
|
238
|
-
console.error(
|
|
239
|
-
return { threads: [] }
|
|
238
|
+
console.error("Error listing chats:", error);
|
|
239
|
+
return { threads: [] };
|
|
240
240
|
}
|
|
241
241
|
},
|
|
242
242
|
|
|
@@ -245,26 +245,26 @@ export function useGramThreadListAdapter(
|
|
|
245
245
|
if (isLocalThreadId(threadId)) {
|
|
246
246
|
// Check if transport already generated a UUID for this local ID
|
|
247
247
|
const existingUuid =
|
|
248
|
-
optionsRef.current.localIdToUuidMap?.get(threadId)
|
|
248
|
+
optionsRef.current.localIdToUuidMap?.get(threadId);
|
|
249
249
|
if (existingUuid) {
|
|
250
250
|
return {
|
|
251
251
|
remoteId: existingUuid,
|
|
252
252
|
externalId: existingUuid,
|
|
253
|
-
}
|
|
253
|
+
};
|
|
254
254
|
}
|
|
255
255
|
// Otherwise generate a new one and store it
|
|
256
|
-
const uuid = crypto.randomUUID()
|
|
257
|
-
optionsRef.current.localIdToUuidMap?.set(threadId, uuid)
|
|
256
|
+
const uuid = crypto.randomUUID();
|
|
257
|
+
optionsRef.current.localIdToUuidMap?.set(threadId, uuid);
|
|
258
258
|
return {
|
|
259
259
|
remoteId: uuid,
|
|
260
260
|
externalId: uuid,
|
|
261
|
-
}
|
|
261
|
+
};
|
|
262
262
|
}
|
|
263
263
|
// For existing threads, use the ID as-is
|
|
264
264
|
return {
|
|
265
265
|
remoteId: threadId,
|
|
266
266
|
externalId: threadId,
|
|
267
|
-
}
|
|
267
|
+
};
|
|
268
268
|
},
|
|
269
269
|
|
|
270
270
|
async rename() {
|
|
@@ -286,53 +286,53 @@ export function useGramThreadListAdapter(
|
|
|
286
286
|
async generateTitle(
|
|
287
287
|
remoteId: string,
|
|
288
288
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
289
|
-
_messages: readonly ThreadMessage[]
|
|
289
|
+
_messages: readonly ThreadMessage[],
|
|
290
290
|
): Promise<AssistantStream> {
|
|
291
291
|
// Skip if this is a local ID that hasn't been persisted yet
|
|
292
292
|
if (!remoteId || isLocalThreadId(remoteId)) {
|
|
293
293
|
return createAssistantStream((controller) => {
|
|
294
|
-
controller.close()
|
|
295
|
-
})
|
|
294
|
+
controller.close();
|
|
295
|
+
});
|
|
296
296
|
}
|
|
297
297
|
|
|
298
298
|
// Title generation happens async server-side via Temporal after first completion.
|
|
299
299
|
// This delay allows the OpenRouter LLM call to complete before we fetch the title.
|
|
300
|
-
const TITLE_GENERATION_DELAY_MS = 2000
|
|
301
|
-
await new Promise((r) => setTimeout(r, TITLE_GENERATION_DELAY_MS))
|
|
300
|
+
const TITLE_GENERATION_DELAY_MS = 2000;
|
|
301
|
+
await new Promise((r) => setTimeout(r, TITLE_GENERATION_DELAY_MS));
|
|
302
302
|
|
|
303
303
|
try {
|
|
304
304
|
// TODO: rename generateTitle endpoint to getTitle
|
|
305
305
|
const response = await fetch(
|
|
306
306
|
`${optionsRef.current.apiUrl}/rpc/chat.generateTitle`,
|
|
307
307
|
{
|
|
308
|
-
method:
|
|
308
|
+
method: "POST",
|
|
309
309
|
headers: {
|
|
310
310
|
...optionsRef.current.headers,
|
|
311
|
-
|
|
311
|
+
"Content-Type": "application/json",
|
|
312
312
|
},
|
|
313
313
|
body: JSON.stringify({ id: remoteId }),
|
|
314
|
-
}
|
|
315
|
-
)
|
|
314
|
+
},
|
|
315
|
+
);
|
|
316
316
|
|
|
317
317
|
if (response.ok) {
|
|
318
|
-
const result = (await response.json()) as { title: string }
|
|
319
|
-
const title = result.title
|
|
318
|
+
const result = (await response.json()) as { title: string };
|
|
319
|
+
const title = result.title;
|
|
320
320
|
|
|
321
321
|
if (title) {
|
|
322
322
|
return createAssistantStream((controller) => {
|
|
323
|
-
controller.appendText(title)
|
|
324
|
-
controller.close()
|
|
325
|
-
})
|
|
323
|
+
controller.appendText(title);
|
|
324
|
+
controller.close();
|
|
325
|
+
});
|
|
326
326
|
}
|
|
327
327
|
}
|
|
328
328
|
} catch (error) {
|
|
329
|
-
console.error(
|
|
329
|
+
console.error("Error fetching title:", error);
|
|
330
330
|
}
|
|
331
331
|
|
|
332
332
|
// If title fetch failed or got placeholder, return empty stream (keeps existing title)
|
|
333
333
|
return createAssistantStream((controller) => {
|
|
334
|
-
controller.close()
|
|
335
|
-
})
|
|
334
|
+
controller.close();
|
|
335
|
+
});
|
|
336
336
|
},
|
|
337
337
|
|
|
338
338
|
async fetch(threadId: string) {
|
|
@@ -340,8 +340,8 @@ export function useGramThreadListAdapter(
|
|
|
340
340
|
if (!threadId || isLocalThreadId(threadId)) {
|
|
341
341
|
return {
|
|
342
342
|
remoteId: threadId,
|
|
343
|
-
status:
|
|
344
|
-
}
|
|
343
|
+
status: "regular" as const,
|
|
344
|
+
};
|
|
345
345
|
}
|
|
346
346
|
|
|
347
347
|
try {
|
|
@@ -349,33 +349,33 @@ export function useGramThreadListAdapter(
|
|
|
349
349
|
`${optionsRef.current.apiUrl}/rpc/chat.load?id=${encodeURIComponent(threadId)}`,
|
|
350
350
|
{
|
|
351
351
|
headers: optionsRef.current.headers,
|
|
352
|
-
}
|
|
353
|
-
)
|
|
352
|
+
},
|
|
353
|
+
);
|
|
354
354
|
|
|
355
355
|
if (!response.ok) {
|
|
356
|
-
console.error(
|
|
356
|
+
console.error("Failed to fetch thread:", response.status);
|
|
357
357
|
return {
|
|
358
358
|
remoteId: threadId,
|
|
359
|
-
status:
|
|
360
|
-
}
|
|
359
|
+
status: "regular" as const,
|
|
360
|
+
};
|
|
361
361
|
}
|
|
362
362
|
|
|
363
|
-
const chat = await response.json()
|
|
363
|
+
const chat = await response.json();
|
|
364
364
|
return {
|
|
365
365
|
remoteId: chat.id,
|
|
366
366
|
externalId: chat.id,
|
|
367
|
-
status:
|
|
368
|
-
title: chat.title ||
|
|
369
|
-
}
|
|
367
|
+
status: "regular" as const,
|
|
368
|
+
title: chat.title || "New Chat",
|
|
369
|
+
};
|
|
370
370
|
} catch (error) {
|
|
371
|
-
console.error(
|
|
371
|
+
console.error("Error fetching thread:", error);
|
|
372
372
|
return {
|
|
373
373
|
remoteId: threadId,
|
|
374
|
-
status:
|
|
375
|
-
}
|
|
374
|
+
status: "regular" as const,
|
|
375
|
+
};
|
|
376
376
|
}
|
|
377
377
|
},
|
|
378
378
|
}),
|
|
379
|
-
[unstable_Provider]
|
|
380
|
-
)
|
|
379
|
+
[unstable_Provider],
|
|
380
|
+
);
|
|
381
381
|
}
|
package/src/hooks/useMCPTools.ts
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
|
-
import { assert } from
|
|
2
|
-
import { ToolsFilter } from
|
|
3
|
-
import { experimental_createMCPClient as createMCPClient } from
|
|
4
|
-
import { useQuery, type UseQueryResult } from
|
|
5
|
-
import { useMemo, useRef } from
|
|
6
|
-
import { Auth } from
|
|
1
|
+
import { assert } from "@/lib/utils";
|
|
2
|
+
import { ToolsFilter } from "@/types";
|
|
3
|
+
import { experimental_createMCPClient as createMCPClient } from "@ai-sdk/mcp";
|
|
4
|
+
import { useQuery, type UseQueryResult } from "@tanstack/react-query";
|
|
5
|
+
import { useMemo, useRef } from "react";
|
|
6
|
+
import { Auth } from "./useAuth";
|
|
7
7
|
|
|
8
8
|
type MCPToolsResult = Awaited<
|
|
9
|
-
ReturnType<Awaited<ReturnType<typeof createMCPClient>>[
|
|
10
|
-
|
|
9
|
+
ReturnType<Awaited<ReturnType<typeof createMCPClient>>["tools"]>
|
|
10
|
+
>;
|
|
11
11
|
|
|
12
12
|
export function useMCPTools({
|
|
13
13
|
auth,
|
|
@@ -16,108 +16,108 @@ export function useMCPTools({
|
|
|
16
16
|
toolsToInclude,
|
|
17
17
|
gramEnvironment,
|
|
18
18
|
}: {
|
|
19
|
-
auth: Auth
|
|
20
|
-
mcp: string | undefined
|
|
21
|
-
environment: Record<string, unknown
|
|
22
|
-
toolsToInclude?: ToolsFilter
|
|
23
|
-
gramEnvironment?: string
|
|
19
|
+
auth: Auth;
|
|
20
|
+
mcp: string | undefined;
|
|
21
|
+
environment: Record<string, unknown>;
|
|
22
|
+
toolsToInclude?: ToolsFilter;
|
|
23
|
+
gramEnvironment?: string;
|
|
24
24
|
}): UseQueryResult<MCPToolsResult, Error> & {
|
|
25
|
-
mcpHeaders: Record<string, string
|
|
25
|
+
mcpHeaders: Record<string, string>;
|
|
26
26
|
} {
|
|
27
27
|
const envQueryKey = Object.entries(environment ?? {}).map(
|
|
28
|
-
([k, v]) => `${k}:${v}
|
|
29
|
-
)
|
|
28
|
+
([k, v]) => `${k}:${v}`,
|
|
29
|
+
);
|
|
30
30
|
const authQueryKey = Object.entries(auth.headers ?? {}).map(
|
|
31
|
-
([k, v]) => `${k}:${v}
|
|
32
|
-
)
|
|
31
|
+
([k, v]) => `${k}:${v}`,
|
|
32
|
+
);
|
|
33
33
|
|
|
34
34
|
// Mutable headers object shared with the MCP transport. The transport stores
|
|
35
35
|
// a direct reference (`this.headers = headers`) and spreads it on every
|
|
36
36
|
// send() call, so mutating properties on this object (e.g. setting
|
|
37
37
|
// Gram-Chat-ID later) will be picked up by subsequent tool call requests.
|
|
38
|
-
const mcpHeaders = useRef<Record<string, string>>({}).current
|
|
38
|
+
const mcpHeaders = useRef<Record<string, string>>({}).current;
|
|
39
39
|
|
|
40
40
|
const queryResult = useQuery({
|
|
41
41
|
queryKey: [
|
|
42
|
-
|
|
42
|
+
"mcpTools",
|
|
43
43
|
mcp,
|
|
44
44
|
gramEnvironment,
|
|
45
45
|
...envQueryKey,
|
|
46
46
|
...authQueryKey,
|
|
47
47
|
],
|
|
48
48
|
queryFn: async () => {
|
|
49
|
-
assert(!auth.isLoading,
|
|
50
|
-
assert(mcp,
|
|
49
|
+
assert(!auth.isLoading, "No auth found");
|
|
50
|
+
assert(mcp, "No MCP URL found");
|
|
51
51
|
|
|
52
52
|
// Populate the shared headers object (mutate in place so the same
|
|
53
53
|
// reference is used by the transport).
|
|
54
|
-
Object.keys(mcpHeaders).forEach((k) => delete mcpHeaders[k])
|
|
54
|
+
Object.keys(mcpHeaders).forEach((k) => delete mcpHeaders[k]);
|
|
55
55
|
Object.assign(mcpHeaders, {
|
|
56
56
|
...transformEnvironmentToHeaders(environment ?? {}),
|
|
57
57
|
...auth.headers,
|
|
58
|
-
...(gramEnvironment && {
|
|
59
|
-
})
|
|
58
|
+
...(gramEnvironment && { "Gram-Environment": gramEnvironment }),
|
|
59
|
+
});
|
|
60
60
|
|
|
61
61
|
const mcpClient = await createMCPClient({
|
|
62
|
-
name:
|
|
62
|
+
name: "gram-elements-mcp-client",
|
|
63
63
|
transport: {
|
|
64
|
-
type:
|
|
64
|
+
type: "http",
|
|
65
65
|
url: mcp,
|
|
66
66
|
headers: mcpHeaders,
|
|
67
67
|
},
|
|
68
|
-
})
|
|
68
|
+
});
|
|
69
69
|
|
|
70
|
-
return mcpClient.tools()
|
|
70
|
+
return mcpClient.tools();
|
|
71
71
|
},
|
|
72
72
|
enabled: !auth.isLoading && !!mcp,
|
|
73
73
|
staleTime: Infinity,
|
|
74
74
|
gcTime: Infinity,
|
|
75
|
-
})
|
|
75
|
+
});
|
|
76
76
|
|
|
77
77
|
// Filter tools outside of the query to ensure filtering is applied whenever
|
|
78
78
|
// toolsToInclude changes, even when the cached query result is reused.
|
|
79
79
|
const tools = useMemo(() => {
|
|
80
80
|
if (!queryResult.data || !toolsToInclude) {
|
|
81
|
-
return queryResult.data
|
|
81
|
+
return queryResult.data;
|
|
82
82
|
}
|
|
83
83
|
|
|
84
84
|
return Object.fromEntries(
|
|
85
85
|
Object.entries(queryResult.data).filter(([name]) =>
|
|
86
|
-
typeof toolsToInclude ===
|
|
86
|
+
typeof toolsToInclude === "function"
|
|
87
87
|
? toolsToInclude({ toolName: name })
|
|
88
|
-
: toolsToInclude.includes(name)
|
|
89
|
-
)
|
|
90
|
-
)
|
|
91
|
-
}, [queryResult.data, toolsToInclude])
|
|
88
|
+
: toolsToInclude.includes(name),
|
|
89
|
+
),
|
|
90
|
+
);
|
|
91
|
+
}, [queryResult.data, toolsToInclude]);
|
|
92
92
|
|
|
93
93
|
return {
|
|
94
94
|
...queryResult,
|
|
95
95
|
data: tools,
|
|
96
96
|
mcpHeaders,
|
|
97
97
|
} as UseQueryResult<MCPToolsResult, Error> & {
|
|
98
|
-
mcpHeaders: Record<string, string
|
|
99
|
-
}
|
|
98
|
+
mcpHeaders: Record<string, string>;
|
|
99
|
+
};
|
|
100
100
|
}
|
|
101
101
|
|
|
102
|
-
const HEADER_PREFIX =
|
|
102
|
+
const HEADER_PREFIX = "MCP-";
|
|
103
103
|
|
|
104
104
|
function transformEnvironmentToHeaders(environment: Record<string, unknown>) {
|
|
105
|
-
if (typeof environment !==
|
|
106
|
-
return {}
|
|
105
|
+
if (typeof environment !== "object" || environment === null) {
|
|
106
|
+
return {};
|
|
107
107
|
}
|
|
108
108
|
return Object.entries(environment).reduce(
|
|
109
109
|
(acc, [key, value]) => {
|
|
110
110
|
// Normalize key: replace underscores with dashes
|
|
111
|
-
const normalizedKey = key.replace(/_/g,
|
|
111
|
+
const normalizedKey = key.replace(/_/g, "-");
|
|
112
112
|
|
|
113
113
|
// Add MCP- prefix if it doesn't already have it
|
|
114
114
|
const headerKey = normalizedKey.startsWith(HEADER_PREFIX)
|
|
115
115
|
? normalizedKey
|
|
116
|
-
: `${HEADER_PREFIX}${normalizedKey}
|
|
116
|
+
: `${HEADER_PREFIX}${normalizedKey}`;
|
|
117
117
|
|
|
118
|
-
acc[headerKey] = value as string
|
|
119
|
-
return acc
|
|
118
|
+
acc[headerKey] = value as string;
|
|
119
|
+
return acc;
|
|
120
120
|
},
|
|
121
|
-
{} as Record<string, string
|
|
122
|
-
)
|
|
121
|
+
{} as Record<string, string>,
|
|
122
|
+
);
|
|
123
123
|
}
|
package/src/hooks/useModel.ts
CHANGED
|
@@ -1,30 +1,30 @@
|
|
|
1
|
-
import { getApiUrl } from
|
|
2
|
-
import { createOpenRouter } from
|
|
3
|
-
import { LanguageModel } from
|
|
4
|
-
import { useAuth } from
|
|
5
|
-
import { useElements } from
|
|
1
|
+
import { getApiUrl } from "@/lib/api";
|
|
2
|
+
import { createOpenRouter } from "@openrouter/ai-sdk-provider";
|
|
3
|
+
import { LanguageModel } from "ai";
|
|
4
|
+
import { useAuth } from "./useAuth";
|
|
5
|
+
import { useElements } from "./useElements";
|
|
6
6
|
|
|
7
7
|
// Creates an OpenRouter client to be used for "internal Gram" usage, such as follow-on suggestions
|
|
8
8
|
export const useModel = (
|
|
9
|
-
model: string =
|
|
9
|
+
model: string = "openai/gpt-4o-mini",
|
|
10
10
|
): LanguageModel => {
|
|
11
|
-
const { config } = useElements()
|
|
11
|
+
const { config } = useElements();
|
|
12
12
|
|
|
13
13
|
const auth = useAuth({
|
|
14
14
|
auth: config.api,
|
|
15
15
|
projectSlug: config.projectSlug,
|
|
16
|
-
})
|
|
16
|
+
});
|
|
17
17
|
|
|
18
|
-
const apiUrl = getApiUrl(config)
|
|
18
|
+
const apiUrl = getApiUrl(config);
|
|
19
19
|
|
|
20
20
|
const openRouter = createOpenRouter({
|
|
21
21
|
baseURL: apiUrl,
|
|
22
|
-
apiKey:
|
|
22
|
+
apiKey: "unused, but must be set",
|
|
23
23
|
headers: {
|
|
24
24
|
...auth.headers,
|
|
25
|
-
|
|
25
|
+
"X-Gram-Source": "gram",
|
|
26
26
|
},
|
|
27
|
-
})
|
|
27
|
+
});
|
|
28
28
|
|
|
29
|
-
return openRouter.chat(model)
|
|
30
|
-
}
|
|
29
|
+
return openRouter.chat(model) as LanguageModel;
|
|
30
|
+
};
|
|
@@ -1,25 +1,25 @@
|
|
|
1
1
|
import {
|
|
2
2
|
CodeHeaderProps,
|
|
3
3
|
SyntaxHighlighterProps,
|
|
4
|
-
} from
|
|
5
|
-
import { ComponentType, useMemo } from
|
|
6
|
-
import { Plugin } from
|
|
4
|
+
} from "@assistant-ui/react-markdown";
|
|
5
|
+
import { ComponentType, useMemo } from "react";
|
|
6
|
+
import { Plugin } from "@/types/plugins";
|
|
7
7
|
|
|
8
8
|
type ComponentsByLanguage =
|
|
9
9
|
| Record<
|
|
10
10
|
string,
|
|
11
11
|
{
|
|
12
|
-
CodeHeader?: ComponentType<CodeHeaderProps> | undefined
|
|
13
|
-
SyntaxHighlighter?: ComponentType<SyntaxHighlighterProps> | undefined
|
|
12
|
+
CodeHeader?: ComponentType<CodeHeaderProps> | undefined;
|
|
13
|
+
SyntaxHighlighter?: ComponentType<SyntaxHighlighterProps> | undefined;
|
|
14
14
|
}
|
|
15
15
|
>
|
|
16
|
-
| undefined
|
|
16
|
+
| undefined;
|
|
17
17
|
|
|
18
18
|
export function useComponentsByLanguage(plugins: Plugin[]) {
|
|
19
19
|
return useMemo(() => {
|
|
20
20
|
return plugins.reduce((acc, plugin) => {
|
|
21
21
|
if (acc?.[plugin.language] && !plugin.overrideExisting) {
|
|
22
|
-
return acc
|
|
22
|
+
return acc;
|
|
23
23
|
}
|
|
24
24
|
acc = {
|
|
25
25
|
...acc,
|
|
@@ -27,8 +27,8 @@ export function useComponentsByLanguage(plugins: Plugin[]) {
|
|
|
27
27
|
CodeHeader: plugin.Header ?? (() => null),
|
|
28
28
|
SyntaxHighlighter: plugin.Component ?? undefined,
|
|
29
29
|
},
|
|
30
|
-
}
|
|
31
|
-
return acc
|
|
32
|
-
}, {} as ComponentsByLanguage)
|
|
33
|
-
}, [plugins])
|
|
30
|
+
};
|
|
31
|
+
return acc;
|
|
32
|
+
}, {} as ComponentsByLanguage);
|
|
33
|
+
}, [plugins]);
|
|
34
34
|
}
|