@mitodl/smoot-design 6.2.2 → 6.4.0
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 +4 -0
- package/dist/bundles/remoteTutorDrawer.es.js +16894 -16636
- package/dist/bundles/remoteTutorDrawer.umd.js +88 -55
- package/dist/cjs/ai.d.ts +3 -3
- package/dist/cjs/ai.js +5 -1
- package/dist/cjs/bundles/RemoteTutorDrawer/FlashcardsScreen.js +1 -1
- package/dist/cjs/bundles/RemoteTutorDrawer/RemoteTutorDrawer.d.ts +1 -2
- package/dist/cjs/bundles/RemoteTutorDrawer/RemoteTutorDrawer.js +11 -5
- package/dist/cjs/bundles/RemoteTutorDrawer/RemoteTutorDrawer.stories.d.ts +1 -0
- package/dist/cjs/bundles/RemoteTutorDrawer/RemoteTutorDrawer.stories.js +21 -2
- package/dist/cjs/bundles/RemoteTutorDrawer/RemoteTutorDrawer.test.js +6 -0
- package/dist/cjs/bundles/remoteTutorDrawer.js +4 -1
- package/dist/cjs/components/AiChat/AiChat.d.ts +3 -3
- package/dist/cjs/components/AiChat/AiChat.js +28 -44
- package/dist/cjs/components/AiChat/AiChat.stories.js +16 -2
- package/dist/cjs/components/AiChat/AiChatContext.d.ts +26 -0
- package/dist/cjs/components/AiChat/AiChatContext.js +105 -0
- package/dist/cjs/components/AiChat/AiChatContext.stories.d.ts +14 -0
- package/dist/cjs/components/AiChat/AiChatContext.stories.js +75 -0
- package/dist/cjs/components/AiChat/Markdown.d.ts +7 -0
- package/dist/cjs/components/AiChat/Markdown.js +14 -0
- package/dist/cjs/components/AiChat/test-utils/api.js +40 -1
- package/dist/cjs/components/AiChat/types.d.ts +20 -11
- package/dist/cjs/components/AiChat/types.js +1 -1
- package/dist/cjs/components/AiChat/utils.d.ts +1 -1
- package/dist/cjs/components/AiChat/utils.js +1 -1
- package/dist/cjs/components/LinkAdapter/LinkAdapter.js +1 -1
- package/dist/cjs/components/TabButtons/TabButtonList.js +1 -1
- package/dist/esm/ai.d.ts +3 -3
- package/dist/esm/ai.js +2 -1
- package/dist/esm/bundles/RemoteTutorDrawer/FlashcardsScreen.js +1 -1
- package/dist/esm/bundles/RemoteTutorDrawer/RemoteTutorDrawer.d.ts +1 -2
- package/dist/esm/bundles/RemoteTutorDrawer/RemoteTutorDrawer.js +11 -5
- package/dist/esm/bundles/RemoteTutorDrawer/RemoteTutorDrawer.stories.d.ts +1 -0
- package/dist/esm/bundles/RemoteTutorDrawer/RemoteTutorDrawer.stories.js +20 -1
- package/dist/esm/bundles/RemoteTutorDrawer/RemoteTutorDrawer.test.js +6 -0
- package/dist/esm/bundles/remoteTutorDrawer.js +4 -1
- package/dist/esm/components/AiChat/AiChat.d.ts +3 -3
- package/dist/esm/components/AiChat/AiChat.js +28 -45
- package/dist/esm/components/AiChat/AiChat.stories.js +16 -2
- package/dist/esm/components/AiChat/AiChatContext.d.ts +26 -0
- package/dist/esm/components/AiChat/AiChatContext.js +101 -0
- package/dist/esm/components/AiChat/AiChatContext.stories.d.ts +14 -0
- package/dist/esm/components/AiChat/AiChatContext.stories.js +72 -0
- package/dist/esm/components/AiChat/Markdown.d.ts +7 -0
- package/dist/esm/components/AiChat/Markdown.js +12 -0
- package/dist/esm/components/AiChat/test-utils/api.js +40 -1
- package/dist/esm/components/AiChat/types.d.ts +20 -11
- package/dist/esm/components/AiChat/types.js +1 -1
- package/dist/esm/components/AiChat/utils.d.ts +1 -1
- package/dist/esm/components/AiChat/utils.js +1 -1
- package/dist/esm/components/LinkAdapter/LinkAdapter.js +1 -1
- package/dist/esm/components/TabButtons/TabButtonList.js +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +8 -7
package/dist/cjs/ai.d.ts
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
export { AiChat } from "./components/AiChat/AiChat";
|
|
2
|
-
export
|
|
3
|
-
export type { AiChatMessage } from "./components/AiChat/types";
|
|
1
|
+
export { AiChat, AiChatDisplay } from "./components/AiChat/AiChat";
|
|
2
|
+
export { AiChatProvider, useAiChat } from "./components/AiChat/AiChatContext";
|
|
3
|
+
export type { AiChatMessage, AiChatContextProps, AiChatDisplayProps, AiChatProps, } from "./components/AiChat/types";
|
package/dist/cjs/ai.js
CHANGED
|
@@ -1,5 +1,9 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.AiChat = void 0;
|
|
3
|
+
exports.useAiChat = exports.AiChatProvider = exports.AiChatDisplay = exports.AiChat = void 0;
|
|
4
4
|
var AiChat_1 = require("./components/AiChat/AiChat");
|
|
5
5
|
Object.defineProperty(exports, "AiChat", { enumerable: true, get: function () { return AiChat_1.AiChat; } });
|
|
6
|
+
Object.defineProperty(exports, "AiChatDisplay", { enumerable: true, get: function () { return AiChat_1.AiChatDisplay; } });
|
|
7
|
+
var AiChatContext_1 = require("./components/AiChat/AiChatContext");
|
|
8
|
+
Object.defineProperty(exports, "AiChatProvider", { enumerable: true, get: function () { return AiChatContext_1.AiChatProvider; } });
|
|
9
|
+
Object.defineProperty(exports, "useAiChat", { enumerable: true, get: function () { return AiChatContext_1.useAiChat; } });
|
|
@@ -38,7 +38,7 @@ const Flashcard = React.forwardRef(({ content, "aria-label": ariaLabel }, ref) =
|
|
|
38
38
|
setScreen(screen === 0 ? 1 : 0);
|
|
39
39
|
}
|
|
40
40
|
};
|
|
41
|
-
return (React.createElement(FlashcardContainer, { ref: ref, onClick: () => setScreen(screen === 0 ? 1 : 0), onKeyDown: handleKeyDown, tabIndex: 0, "aria-label": ariaLabel },
|
|
41
|
+
return (React.createElement(FlashcardContainer, { ref: ref, onClick: () => setScreen(screen === 0 ? 1 : 0), onKeyDown: handleKeyDown, tabIndex: 0, "aria-label": ariaLabel, role: "button" },
|
|
42
42
|
React.createElement(Typography_1.default, { variant: "h5" }, screen === 0 ? `Q: ${content.question}` : `Answer: ${content.answer}`)));
|
|
43
43
|
});
|
|
44
44
|
Flashcard.displayName = "Flashcard";
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { FC } from "react";
|
|
2
|
-
import { AiChatMessage } from "../../components/AiChat/types";
|
|
3
|
-
import type { AiChatProps } from "../../components/AiChat/AiChat";
|
|
2
|
+
import type { AiChatProps, AiChatMessage } from "../../components/AiChat/types";
|
|
4
3
|
type RemoteTutorDrawerInitMessage = {
|
|
5
4
|
type: "smoot-design::tutor-drawer-open";
|
|
6
5
|
payload: {
|
|
@@ -152,6 +152,12 @@ const useContentFetch = (contentUrl) => {
|
|
|
152
152
|
}, [contentUrl]);
|
|
153
153
|
return { response, loading };
|
|
154
154
|
};
|
|
155
|
+
const DEFAULT_PROBLEM_INITIAL_MESSAGES = [
|
|
156
|
+
{
|
|
157
|
+
role: "assistant",
|
|
158
|
+
content: "Let's try to work on this problem together. It would be great to hear how you're thinking about solving it. Can you walk me through the approach you're considering?",
|
|
159
|
+
},
|
|
160
|
+
];
|
|
155
161
|
const DEFAULT_VIDEO_ENTRY_SCREEN_TITLE = "What do you want to know about this video?";
|
|
156
162
|
const DEFAULT_VIDEO_STARTERS = [
|
|
157
163
|
{ content: "What are the most important concepts introduced in the video?" },
|
|
@@ -160,14 +166,14 @@ const DEFAULT_VIDEO_STARTERS = [
|
|
|
160
166
|
},
|
|
161
167
|
{ content: "What are the key terms introduced in this video?" },
|
|
162
168
|
];
|
|
163
|
-
const ChatComponent = ({ payload, transformBody, fetchOpts, scrollElement, entryScreenEnabled, entryScreenTitle, conversationStarters, hasTabs, }) => {
|
|
169
|
+
const ChatComponent = ({ payload, transformBody, fetchOpts, scrollElement, entryScreenEnabled, entryScreenTitle, conversationStarters, initialMessages, hasTabs, needsMathJax, }) => {
|
|
164
170
|
if (!payload)
|
|
165
171
|
return null;
|
|
166
|
-
return (React.createElement(StyledAiChat, { chatId: payload.chatId, conversationStarters: conversationStarters, initialMessages:
|
|
172
|
+
return (React.createElement(StyledAiChat, { chatId: payload.chatId, conversationStarters: conversationStarters, initialMessages: initialMessages, scrollElement: scrollElement, entryScreenEnabled: entryScreenEnabled, entryScreenTitle: entryScreenTitle, requestOpts: {
|
|
167
173
|
transformBody: (messages) => (Object.assign(Object.assign({}, payload.requestBody), transformBody === null || transformBody === void 0 ? void 0 : transformBody(messages))),
|
|
168
174
|
apiUrl: payload.apiUrl,
|
|
169
175
|
fetchOpts: Object.assign(Object.assign({}, DEFAULT_FETCH_OPTS), fetchOpts),
|
|
170
|
-
}, hasTabs: hasTabs }));
|
|
176
|
+
}, hasTabs: hasTabs, useMathJax: needsMathJax }));
|
|
171
177
|
};
|
|
172
178
|
const randomItems = (array, count) => {
|
|
173
179
|
const shuffled = [...array].sort(() => 0.5 - Math.random());
|
|
@@ -258,14 +264,14 @@ const RemoteTutorDrawer = ({ messageOrigin, transformBody = identity, className,
|
|
|
258
264
|
payload.title.replace("AskTIM", ""))) : (payload.title))),
|
|
259
265
|
React.createElement(CloseButton, { variant: "text", size: "medium", onClick: () => setOpen(false), "aria-label": "Close" },
|
|
260
266
|
React.createElement(react_2.RiCloseLine, null))),
|
|
261
|
-
blockType === "problem" ? (React.createElement(ChatComponent, { payload: chat, transformBody: transformBody, fetchOpts: fetchOpts, scrollElement: scrollElement, entryScreenEnabled: (_d = (_c = payload.chat) === null || _c === void 0 ? void 0 : _c.entryScreenEnabled) !== null && _d !== void 0 ? _d : false, entryScreenTitle: payload.chat.entryScreenTitle, hasTabs: hasTabs })) : null,
|
|
267
|
+
blockType === "problem" ? (React.createElement(ChatComponent, { payload: chat, transformBody: transformBody, fetchOpts: fetchOpts, scrollElement: scrollElement, entryScreenEnabled: (_d = (_c = payload.chat) === null || _c === void 0 ? void 0 : _c.entryScreenEnabled) !== null && _d !== void 0 ? _d : false, entryScreenTitle: payload.chat.entryScreenTitle, initialMessages: payload.chat.initialMessages || DEFAULT_PROBLEM_INITIAL_MESSAGES, hasTabs: hasTabs, needsMathJax: true })) : null,
|
|
262
268
|
blockType === "video" ? (React.createElement(TabContext_1.default, { value: tab },
|
|
263
269
|
React.createElement(StyledTabButtonList, { styleVariant: "chat", onChange: (e, tab) => setTab(tab) },
|
|
264
270
|
React.createElement(TabButtonList_1.TabButton, { value: "chat", label: "Chat" }),
|
|
265
271
|
((_e = response === null || response === void 0 ? void 0 : response.flashcards) === null || _e === void 0 ? void 0 : _e.length) ? (React.createElement(TabButtonList_1.TabButton, { value: "flashcards", label: "Flashcards", onMouseDown: handleMouseDown, onFocus: handleFocus })) : null,
|
|
266
272
|
React.createElement(TabButtonList_1.TabButton, { value: "summary", label: "Summary" })),
|
|
267
273
|
React.createElement(StyledTabPanel, { value: "chat", keepMounted: true },
|
|
268
|
-
React.createElement(ChatComponent, { payload: Object.assign({}, chat), transformBody: transformBody, fetchOpts: fetchOpts, scrollElement: scrollElement, entryScreenEnabled: (_g = (_f = payload.chat) === null || _f === void 0 ? void 0 : _f.entryScreenEnabled) !== null && _g !== void 0 ? _g : true, entryScreenTitle: (_h = payload.chat.entryScreenTitle) !== null && _h !== void 0 ? _h : DEFAULT_VIDEO_ENTRY_SCREEN_TITLE, conversationStarters: conversationStarters, hasTabs: hasTabs })),
|
|
274
|
+
React.createElement(ChatComponent, { payload: Object.assign({}, chat), transformBody: transformBody, fetchOpts: fetchOpts, scrollElement: scrollElement, entryScreenEnabled: (_g = (_f = payload.chat) === null || _f === void 0 ? void 0 : _f.entryScreenEnabled) !== null && _g !== void 0 ? _g : true, entryScreenTitle: (_h = payload.chat.entryScreenTitle) !== null && _h !== void 0 ? _h : DEFAULT_VIDEO_ENTRY_SCREEN_TITLE, conversationStarters: conversationStarters, initialMessages: payload.chat.initialMessages, hasTabs: hasTabs, needsMathJax: false })),
|
|
269
275
|
((_j = response === null || response === void 0 ? void 0 : response.flashcards) === null || _j === void 0 ? void 0 : _j.length) ? (React.createElement(StyledTabPanel, { value: "flashcards" },
|
|
270
276
|
React.createElement(FlashcardsScreen_1.FlashcardsScreen, { flashcards: response === null || response === void 0 ? void 0 : response.flashcards, wasKeyboardFocus: _wasKeyboardFocus }))) : null,
|
|
271
277
|
React.createElement(StyledTabPanel, { value: "summary" },
|
|
@@ -4,6 +4,7 @@ declare const meta: Meta<typeof RemoteTutorDrawer>;
|
|
|
4
4
|
export default meta;
|
|
5
5
|
type Story = StoryObj<typeof RemoteTutorDrawer>;
|
|
6
6
|
export declare const ProblemStory: Story;
|
|
7
|
+
export declare const ProblemDefaultInitialMessagesStory: Story;
|
|
7
8
|
export declare const EntryScreenStory: Story;
|
|
8
9
|
/**
|
|
9
10
|
* The chat entry screen is shown by default for the video blocks Tutor drawer.
|
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.FlashcardConversationStartersStory = exports.VideoStory = exports.EntryScreenStory = exports.ProblemStory = void 0;
|
|
3
|
+
exports.FlashcardConversationStartersStory = exports.VideoStory = exports.EntryScreenStory = exports.ProblemDefaultInitialMessagesStory = exports.ProblemStory = void 0;
|
|
4
4
|
/* eslint-disable react-hooks/rules-of-hooks */
|
|
5
5
|
const React = require("react");
|
|
6
6
|
const tiny_invariant_1 = require("tiny-invariant");
|
|
7
7
|
const msw_1 = require("msw");
|
|
8
8
|
const api_1 = require("../../components/AiChat/test-utils/api");
|
|
9
9
|
const RemoteTutorDrawer_1 = require("./RemoteTutorDrawer");
|
|
10
|
+
const better_react_mathjax_1 = require("better-react-mathjax");
|
|
10
11
|
const TEST_API_STREAMING = "http://localhost:4567/streaming";
|
|
11
12
|
const CONTENT_FILE_URL = "http://localhost:4567/api/v1/contentfiles/?edx_module_id=1";
|
|
12
13
|
const INITIAL_MESSAGES = [
|
|
@@ -54,9 +55,11 @@ const IFrame = ({ payload }) => {
|
|
|
54
55
|
};
|
|
55
56
|
const meta = {
|
|
56
57
|
title: "smoot-design/AI/RemoteTutorDrawer",
|
|
58
|
+
component: RemoteTutorDrawer_1.RemoteTutorDrawer,
|
|
57
59
|
render: ({ target }, { parameters: { payload } }) => (React.createElement(React.Fragment, null,
|
|
58
60
|
React.createElement(IFrame, { payload: payload }),
|
|
59
|
-
React.createElement(
|
|
61
|
+
React.createElement(better_react_mathjax_1.MathJaxContext, null,
|
|
62
|
+
React.createElement(RemoteTutorDrawer_1.RemoteTutorDrawer, { target: target, messageOrigin: "http://localhost:6006" })))),
|
|
60
63
|
};
|
|
61
64
|
exports.default = meta;
|
|
62
65
|
exports.ProblemStory = {
|
|
@@ -76,6 +79,22 @@ exports.ProblemStory = {
|
|
|
76
79
|
},
|
|
77
80
|
},
|
|
78
81
|
};
|
|
82
|
+
exports.ProblemDefaultInitialMessagesStory = {
|
|
83
|
+
args: {
|
|
84
|
+
target: "problem-frame-default-initial-messages",
|
|
85
|
+
},
|
|
86
|
+
parameters: {
|
|
87
|
+
payload: {
|
|
88
|
+
blockType: "problem",
|
|
89
|
+
target: "problem-frame-default-initial-messages",
|
|
90
|
+
title: "AskTIM for help with Problem: Derivatives 1.1",
|
|
91
|
+
chat: {
|
|
92
|
+
apiUrl: TEST_API_STREAMING,
|
|
93
|
+
conversationStarters: STARTERS,
|
|
94
|
+
},
|
|
95
|
+
},
|
|
96
|
+
},
|
|
97
|
+
};
|
|
79
98
|
exports.EntryScreenStory = {
|
|
80
99
|
args: {
|
|
81
100
|
target: "entry-screen-frame",
|
|
@@ -16,6 +16,12 @@ const ThemeProvider_1 = require("../../components/ThemeProvider/ThemeProvider");
|
|
|
16
16
|
const React = require("react");
|
|
17
17
|
const msw_1 = require("msw");
|
|
18
18
|
const node_1 = require("msw/node");
|
|
19
|
+
jest.mock("../../components/AiChat/Markdown", () => {
|
|
20
|
+
return {
|
|
21
|
+
__esModule: true,
|
|
22
|
+
default: ({ children }) => React.createElement("div", null, children),
|
|
23
|
+
};
|
|
24
|
+
});
|
|
19
25
|
const TEST_API_STREAMING = "http://localhost:4567/test";
|
|
20
26
|
const CONTENT_FILE_URL = "http://localhost:4567/api/v1/contentfiles/1";
|
|
21
27
|
const CONTENT_RESPONSE = {
|
|
@@ -7,6 +7,7 @@ const RemoteTutorDrawer_1 = require("./RemoteTutorDrawer/RemoteTutorDrawer");
|
|
|
7
7
|
const ThemeProvider_1 = require("../components/ThemeProvider/ThemeProvider");
|
|
8
8
|
const react_1 = require("@emotion/react");
|
|
9
9
|
const cache_1 = require("@emotion/cache");
|
|
10
|
+
const better_react_mathjax_1 = require("better-react-mathjax");
|
|
10
11
|
/**
|
|
11
12
|
* Renders the RemoteTutorDrawer in an shadow DOM in order to isolate the drawer
|
|
12
13
|
* styles from external stylesheets.
|
|
@@ -35,6 +36,8 @@ const init = (opts) => {
|
|
|
35
36
|
});
|
|
36
37
|
(0, client_1.createRoot)(shadowRootEl).render(React.createElement(react_1.CacheProvider, { value: cache },
|
|
37
38
|
React.createElement(ThemeProvider_1.ThemeProvider, { theme: theme },
|
|
38
|
-
React.createElement(
|
|
39
|
+
React.createElement(better_react_mathjax_1.MathJaxContext, null,
|
|
40
|
+
React.createElement(RemoteTutorDrawer_1.RemoteTutorDrawer, Object.assign({}, opts))),
|
|
41
|
+
",")));
|
|
39
42
|
};
|
|
40
43
|
exports.init = init;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { FC } from "react";
|
|
2
|
-
import type { AiChatProps } from "./types";
|
|
2
|
+
import type { AiChatDisplayProps, AiChatProps } from "./types";
|
|
3
|
+
declare const AiChatDisplay: FC<AiChatDisplayProps>;
|
|
3
4
|
declare const AiChat: FC<AiChatProps>;
|
|
4
|
-
export { AiChat };
|
|
5
|
-
export type { AiChatProps };
|
|
5
|
+
export { AiChatDisplay, AiChat };
|
|
@@ -11,7 +11,7 @@ var __rest = (this && this.__rest) || function (s, e) {
|
|
|
11
11
|
return t;
|
|
12
12
|
};
|
|
13
13
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
14
|
-
exports.AiChat = void 0;
|
|
14
|
+
exports.AiChat = exports.AiChatDisplay = void 0;
|
|
15
15
|
const React = require("react");
|
|
16
16
|
const react_1 = require("react");
|
|
17
17
|
const styled_1 = require("@emotion/styled");
|
|
@@ -20,14 +20,14 @@ const classnames_1 = require("classnames");
|
|
|
20
20
|
const react_2 = require("@remixicon/react");
|
|
21
21
|
const Input_1 = require("../Input/Input");
|
|
22
22
|
const EntryScreen_1 = require("./EntryScreen");
|
|
23
|
-
const react_markdown_1 = require("react-markdown");
|
|
24
23
|
const ScrollSnap_1 = require("../ScrollSnap/ScrollSnap");
|
|
25
24
|
const SrAnnouncer_1 = require("../SrAnnouncer/SrAnnouncer");
|
|
26
25
|
const VisuallyHidden_1 = require("../VisuallyHidden/VisuallyHidden");
|
|
27
26
|
const Alert_1 = require("../Alert/Alert");
|
|
28
27
|
const ChatTitle_1 = require("./ChatTitle");
|
|
29
|
-
const
|
|
28
|
+
const AiChatContext_1 = require("./AiChatContext");
|
|
30
29
|
const useScrollSnap_1 = require("../ScrollSnap/useScrollSnap");
|
|
30
|
+
const Markdown_1 = require("./Markdown");
|
|
31
31
|
const classes = {
|
|
32
32
|
root: "MitAiChat--root",
|
|
33
33
|
title: "MitAiChat--title",
|
|
@@ -133,47 +133,27 @@ const Disclaimer = (0, styled_1.default)(Typography_1.default)(({ theme }) => ({
|
|
|
133
133
|
marginTop: "16px",
|
|
134
134
|
textAlign: "center",
|
|
135
135
|
}));
|
|
136
|
-
const
|
|
136
|
+
const AiChatDisplay = (_a) => {
|
|
137
137
|
var _b, _c;
|
|
138
|
-
var {
|
|
138
|
+
var { conversationStarters, askTimTitle, entryScreenEnabled = true, entryScreenTitle, srLoadingMessages, placeholder = "", className, scrollElement, ref, useMathJax = false } = _a, others = __rest(_a, ["conversationStarters", "askTimTitle", "entryScreenEnabled", "entryScreenTitle", "srLoadingMessages", "placeholder", "className", "scrollElement", "ref", "useMathJax"]) // Could contain data attributes
|
|
139
139
|
;
|
|
140
140
|
const containerRef = (0, react_1.useRef)(null);
|
|
141
141
|
const messagesContainerRef = (0, react_1.useRef)(null);
|
|
142
|
-
const [showEntryScreen, setShowEntryScreen] = (0, react_1.useState)(entryScreenEnabled);
|
|
143
142
|
const chatScreenRef = (0, react_1.useRef)(null);
|
|
144
|
-
const [initialMessages, setInitialMessages] = (0, react_1.useState)();
|
|
145
143
|
const promptInputRef = (0, react_1.useRef)(null);
|
|
146
|
-
const { messages
|
|
147
|
-
initialMessages,
|
|
148
|
-
id: chatId,
|
|
149
|
-
});
|
|
144
|
+
const { messages, input, handleInputChange, handleSubmit, append, isLoading, stop, error, initialMessages, } = (0, AiChatContext_1.useAiChat)();
|
|
150
145
|
(0, useScrollSnap_1.useScrollSnap)({
|
|
151
146
|
scrollElement: scrollElement || messagesContainerRef.current,
|
|
152
147
|
contentElement: scrollElement ? messagesContainerRef.current : null,
|
|
153
148
|
threshold: 200,
|
|
154
149
|
});
|
|
155
|
-
(0, react_1.
|
|
156
|
-
if (_initialMessages) {
|
|
157
|
-
const prefix = Math.random().toString().slice(2);
|
|
158
|
-
setInitialMessages(_initialMessages.map((m, i) => (Object.assign(Object.assign({}, m), { id: `initial-${prefix}-${i}` }))));
|
|
159
|
-
}
|
|
160
|
-
}, [_initialMessages]);
|
|
150
|
+
const [showEntryScreen, setShowEntryScreen] = (0, react_1.useState)(entryScreenEnabled);
|
|
161
151
|
(0, react_1.useEffect)(() => {
|
|
162
152
|
var _a, _b;
|
|
163
153
|
if (!showEntryScreen) {
|
|
164
154
|
(_b = (_a = promptInputRef.current) === null || _a === void 0 ? void 0 : _a.querySelector("input")) === null || _b === void 0 ? void 0 : _b.focus();
|
|
165
155
|
}
|
|
166
156
|
}, [showEntryScreen]);
|
|
167
|
-
const messages = (0, react_1.useMemo)(() => {
|
|
168
|
-
const initial = initialMessages === null || initialMessages === void 0 ? void 0 : initialMessages.map((m) => m.id);
|
|
169
|
-
return unparsed.map((m) => {
|
|
170
|
-
if (m.role === "assistant" && !(initial === null || initial === void 0 ? void 0 : initial.includes(m.id))) {
|
|
171
|
-
const content = parseContent ? parseContent(m.content) : m.content;
|
|
172
|
-
return Object.assign(Object.assign({}, m), { content });
|
|
173
|
-
}
|
|
174
|
-
return m;
|
|
175
|
-
});
|
|
176
|
-
}, [parseContent, unparsed, initialMessages]);
|
|
177
157
|
const showStarters = messages.length === ((initialMessages === null || initialMessages === void 0 ? void 0 : initialMessages.length) || 0);
|
|
178
158
|
const waiting = !showStarters && !error && ((_b = messages[messages.length - 1]) === null || _b === void 0 ? void 0 : _b.role) === "user";
|
|
179
159
|
const stoppable = isLoading && ((_c = messages[messages.length - 1]) === null || _c === void 0 ? void 0 : _c.role) !== "user";
|
|
@@ -186,16 +166,7 @@ const AiChat = (_a) => {
|
|
|
186
166
|
};
|
|
187
167
|
const lastMsg = messages[messages.length - 1];
|
|
188
168
|
const externalScroll = !!scrollElement;
|
|
189
|
-
return (React.createElement(Container, { className: className, ref: containerRef,
|
|
190
|
-
/**
|
|
191
|
-
* Changing the `useChat` chatId seems to persist some state between
|
|
192
|
-
* hook calls. This can cause strange effects like loading API responses
|
|
193
|
-
* for previous chatId into new chatId.
|
|
194
|
-
*
|
|
195
|
-
* To avoid this, let's change the key, this will force React to make a new component
|
|
196
|
-
* not sharing any of the old state.
|
|
197
|
-
*/
|
|
198
|
-
key: chatId }, showEntryScreen ? (React.createElement(EntryScreen_1.EntryScreen, { className: classes.entryScreenContainer, title: entryScreenTitle, conversationStarters: conversationStarters, onPromptSubmit: (prompt) => {
|
|
169
|
+
return (React.createElement(Container, { className: className, ref: containerRef }, showEntryScreen ? (React.createElement(EntryScreen_1.EntryScreen, { className: classes.entryScreenContainer, title: entryScreenTitle, conversationStarters: conversationStarters, onPromptSubmit: (prompt) => {
|
|
199
170
|
if (prompt.trim() === "") {
|
|
200
171
|
return;
|
|
201
172
|
}
|
|
@@ -205,13 +176,20 @@ const AiChat = (_a) => {
|
|
|
205
176
|
React.createElement(ChatContainer, Object.assign({ className: (0, classnames_1.default)(className, classes.root), externalScroll: externalScroll }, others),
|
|
206
177
|
React.createElement(ChatTitle_1.ChatTitle, { askTimTitle: askTimTitle, externalScroll: externalScroll, className: (0, classnames_1.default)(className, classes.title) }),
|
|
207
178
|
React.createElement(MessagesContainer, { className: classes.messagesContainer, externalScroll: externalScroll, ref: messagesContainerRef },
|
|
208
|
-
messages.map((m) =>
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
179
|
+
messages.map((m, i) => {
|
|
180
|
+
// Our Markdown+Mathjax has issues when rendering streaming display math
|
|
181
|
+
// Force a re-render of the last (streaming) message when it's done loading.
|
|
182
|
+
const key = i === messages.length - 1 && isLoading
|
|
183
|
+
? `isLoading-${m.id}`
|
|
184
|
+
: m.id;
|
|
185
|
+
return (React.createElement(MessageRow, { key: key, "data-chat-role": m.role, className: (0, classnames_1.default)(classes.messageRow, {
|
|
186
|
+
[classes.messageRowUser]: m.role === "user",
|
|
187
|
+
[classes.messageRowAssistant]: m.role === "assistant",
|
|
188
|
+
}) },
|
|
189
|
+
React.createElement(Message, { className: classes.message },
|
|
190
|
+
React.createElement(VisuallyHidden_1.VisuallyHidden, { as: m.role === "user" ? "h5" : "h6" }, m.role === "user" ? "You said: " : "Assistant said: "),
|
|
191
|
+
React.createElement(Markdown_1.default, { enableMathjax: useMathJax }, m.content))));
|
|
192
|
+
}),
|
|
215
193
|
showStarters ? (React.createElement(StarterContainer, null, conversationStarters === null || conversationStarters === void 0 ? void 0 : conversationStarters.map((m) => (React.createElement(Starter, { className: classes.conversationStarter, key: m.content, onClick: () => {
|
|
216
194
|
scrollToBottom();
|
|
217
195
|
append({ role: "user", content: m.content });
|
|
@@ -246,4 +224,10 @@ const AiChat = (_a) => {
|
|
|
246
224
|
React.createElement(Disclaimer, { variant: "body3" }, "AI-generated content may be incorrect.")),
|
|
247
225
|
React.createElement(SrAnnouncer_1.SrAnnouncer, { isLoading: isLoading, loadingMessages: srLoadingMessages, message: (lastMsg === null || lastMsg === void 0 ? void 0 : lastMsg.role) === "assistant" ? lastMsg === null || lastMsg === void 0 ? void 0 : lastMsg.content : "" }))))));
|
|
248
226
|
};
|
|
227
|
+
exports.AiChatDisplay = AiChatDisplay;
|
|
228
|
+
const AiChat = (_a) => {
|
|
229
|
+
var { requestOpts, initialMessages, chatId, parseContent } = _a, displayProps = __rest(_a, ["requestOpts", "initialMessages", "chatId", "parseContent"]);
|
|
230
|
+
return (React.createElement(AiChatContext_1.AiChatProvider, { requestOpts: requestOpts, chatId: chatId, initialMessages: initialMessages, parseContent: parseContent },
|
|
231
|
+
React.createElement(AiChatDisplay, Object.assign({}, displayProps))));
|
|
232
|
+
};
|
|
249
233
|
exports.AiChat = AiChat;
|
|
@@ -6,6 +6,7 @@ const AiChat_1 = require("./AiChat");
|
|
|
6
6
|
const styled_1 = require("@emotion/styled");
|
|
7
7
|
const api_1 = require("./test-utils/api");
|
|
8
8
|
const react_1 = require("react");
|
|
9
|
+
const better_react_mathjax_1 = require("better-react-mathjax");
|
|
9
10
|
const TEST_API_STREAMING = "http://localhost:4567/streaming";
|
|
10
11
|
const TEST_API_JSON = "http://localhost:4567/json";
|
|
11
12
|
const INITIAL_MESSAGES = [
|
|
@@ -39,8 +40,9 @@ const meta = {
|
|
|
39
40
|
},
|
|
40
41
|
render: (args) => React.createElement(AiChat_1.AiChat, Object.assign({}, args)),
|
|
41
42
|
decorators: (Story, context) => {
|
|
42
|
-
return (React.createElement(
|
|
43
|
-
React.createElement(
|
|
43
|
+
return (React.createElement(better_react_mathjax_1.MathJaxContext, null,
|
|
44
|
+
React.createElement(Container, null,
|
|
45
|
+
React.createElement(Story, { key: String(context.args.entryScreenEnabled) }))));
|
|
44
46
|
},
|
|
45
47
|
args: {
|
|
46
48
|
entryScreenTitle: "What do you want to learn from MIT?",
|
|
@@ -111,6 +113,17 @@ And some inline code, \`\`<inline></inline>\`\` and code block:
|
|
|
111
113
|
def f(x):
|
|
112
114
|
print(x)
|
|
113
115
|
\`\`\`
|
|
116
|
+
|
|
117
|
+
And some inline math: $x = \\frac{-b\\pm\\sqrt{b^2-4ac}}{2a}$
|
|
118
|
+
|
|
119
|
+
And some block math:
|
|
120
|
+
\n
|
|
121
|
+
|
|
122
|
+
$$
|
|
123
|
+
x = \\frac{-b\\pm\\sqrt{b^2-4ac}}{2a}
|
|
124
|
+
$$
|
|
125
|
+
|
|
126
|
+
Math is rendered using MathJax only if the useMathJax prop is set to true.
|
|
114
127
|
`;
|
|
115
128
|
/**
|
|
116
129
|
* This story shows the component's builtin markdown styling.
|
|
@@ -126,6 +139,7 @@ exports.MarkdownStyling = {
|
|
|
126
139
|
content: DEMO_MARKDOWN,
|
|
127
140
|
},
|
|
128
141
|
],
|
|
142
|
+
useMathJax: true,
|
|
129
143
|
},
|
|
130
144
|
};
|
|
131
145
|
const ScrollComponent = (args) => {
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
import { UseChatHelpers } from "@ai-sdk/react";
|
|
3
|
+
import type { AiChatMessage, AiChatContextProps } from "./types";
|
|
4
|
+
/**
|
|
5
|
+
* All of `@ai-sdk/react`'s [`useChat`](https://ai-sdk.dev/docs/reference/ai-sdk-ui/use-chat)
|
|
6
|
+
* results, plus the initial messages.
|
|
7
|
+
*/
|
|
8
|
+
type AiChatContextResult = UseChatHelpers & {
|
|
9
|
+
initialMessages: AiChatMessage[] | null;
|
|
10
|
+
};
|
|
11
|
+
/**
|
|
12
|
+
* Provides AiChatContext to its children. Within this provider, you can consume
|
|
13
|
+
* the AiChatContext using the `useAiChat` hook.
|
|
14
|
+
*/
|
|
15
|
+
declare const AiChatProvider: React.FC<AiChatContextProps>;
|
|
16
|
+
/**
|
|
17
|
+
* Returns the AiChatContext, which includes all results from `@ai-sdk/react`'s
|
|
18
|
+
* [`useChat`](https://ai-sdk.dev/docs/reference/ai-sdk-ui/use-chat) hook as
|
|
19
|
+
* well as the initial messages.
|
|
20
|
+
*
|
|
21
|
+
* In addition to customizing the fetcher, using a context allows us to avoid
|
|
22
|
+
* this issue https://github.com/vercel/ai/issues/3266 since the caller no
|
|
23
|
+
* longer needs to provide the initial messages.
|
|
24
|
+
*/
|
|
25
|
+
declare const useAiChat: () => AiChatContextResult;
|
|
26
|
+
export { useAiChat, AiChatProvider };
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
+
});
|
|
10
|
+
};
|
|
11
|
+
var __rest = (this && this.__rest) || function (s, e) {
|
|
12
|
+
var t = {};
|
|
13
|
+
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
|
|
14
|
+
t[p] = s[p];
|
|
15
|
+
if (s != null && typeof Object.getOwnPropertySymbols === "function")
|
|
16
|
+
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
|
|
17
|
+
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
|
|
18
|
+
t[p[i]] = s[p[i]];
|
|
19
|
+
}
|
|
20
|
+
return t;
|
|
21
|
+
};
|
|
22
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
23
|
+
exports.AiChatProvider = exports.useAiChat = void 0;
|
|
24
|
+
const React = require("react");
|
|
25
|
+
const react_1 = require("@ai-sdk/react");
|
|
26
|
+
const react_2 = require("react");
|
|
27
|
+
const identity = (x) => x;
|
|
28
|
+
const getFetcher = (requestOpts) => (url, opts) => __awaiter(void 0, void 0, void 0, function* () {
|
|
29
|
+
var _a, _b;
|
|
30
|
+
if (typeof (opts === null || opts === void 0 ? void 0 : opts.body) !== "string") {
|
|
31
|
+
console.error("Unexpected body type.");
|
|
32
|
+
return window.fetch(url, opts);
|
|
33
|
+
}
|
|
34
|
+
const messages = JSON.parse(opts === null || opts === void 0 ? void 0 : opts.body).messages;
|
|
35
|
+
const transformBody = (_a = requestOpts.transformBody) !== null && _a !== void 0 ? _a : identity;
|
|
36
|
+
const options = Object.assign(Object.assign(Object.assign(Object.assign({}, opts), { body: JSON.stringify(transformBody(messages)) }), requestOpts.fetchOpts), { headers: Object.assign(Object.assign(Object.assign({}, opts === null || opts === void 0 ? void 0 : opts.headers), { "Content-Type": "application/json" }), (_b = requestOpts.fetchOpts) === null || _b === void 0 ? void 0 : _b.headers) });
|
|
37
|
+
return fetch(url, options);
|
|
38
|
+
});
|
|
39
|
+
const AiChatContext = (0, react_2.createContext)(null);
|
|
40
|
+
/**
|
|
41
|
+
* Provides AiChatContext to its children. Within this provider, you can consume
|
|
42
|
+
* the AiChatContext using the `useAiChat` hook.
|
|
43
|
+
*/
|
|
44
|
+
const AiChatProvider = ({ initialMessages: _initialMessages, requestOpts, chatId, parseContent, children, }) => {
|
|
45
|
+
const initialMessages = (0, react_2.useMemo)(() => {
|
|
46
|
+
var _a;
|
|
47
|
+
return ((_a = _initialMessages === null || _initialMessages === void 0 ? void 0 : _initialMessages.map((message, i) => (Object.assign(Object.assign({}, message), { id: `initial-${i}` })))) !== null && _a !== void 0 ? _a : []);
|
|
48
|
+
}, [_initialMessages]);
|
|
49
|
+
const fetcher = (0, react_2.useMemo)(() => getFetcher(requestOpts), [requestOpts]);
|
|
50
|
+
const _a = (0, react_1.useChat)({
|
|
51
|
+
api: requestOpts.apiUrl,
|
|
52
|
+
streamProtocol: "text",
|
|
53
|
+
fetch: fetcher,
|
|
54
|
+
onFinish: (message) => {
|
|
55
|
+
var _a;
|
|
56
|
+
if (!requestOpts.onFinish)
|
|
57
|
+
return;
|
|
58
|
+
if (message.role === "assistant" || message.role === "user") {
|
|
59
|
+
(_a = requestOpts.onFinish) === null || _a === void 0 ? void 0 : _a.call(requestOpts, message);
|
|
60
|
+
}
|
|
61
|
+
else {
|
|
62
|
+
console.info("Unexpected message role.", message);
|
|
63
|
+
}
|
|
64
|
+
},
|
|
65
|
+
initialMessages,
|
|
66
|
+
id: chatId,
|
|
67
|
+
}), { messages: unparsed } = _a, others = __rest(_a, ["messages"]);
|
|
68
|
+
const messages = (0, react_2.useMemo)(() => {
|
|
69
|
+
const initial = initialMessages === null || initialMessages === void 0 ? void 0 : initialMessages.map((m) => m.id);
|
|
70
|
+
return unparsed.map((m) => {
|
|
71
|
+
if (m.role === "assistant" && !(initial === null || initial === void 0 ? void 0 : initial.includes(m.id))) {
|
|
72
|
+
const content = parseContent ? parseContent(m.content) : m.content;
|
|
73
|
+
return Object.assign(Object.assign({}, m), { content });
|
|
74
|
+
}
|
|
75
|
+
return m;
|
|
76
|
+
});
|
|
77
|
+
}, [parseContent, unparsed, initialMessages]);
|
|
78
|
+
return (React.createElement(AiChatContext.Provider
|
|
79
|
+
/**
|
|
80
|
+
* Ensure that child state is reset when chatId changes.
|
|
81
|
+
*/
|
|
82
|
+
, {
|
|
83
|
+
/**
|
|
84
|
+
* Ensure that child state is reset when chatId changes.
|
|
85
|
+
*/
|
|
86
|
+
key: chatId, value: Object.assign({ initialMessages, messages }, others) }, children));
|
|
87
|
+
};
|
|
88
|
+
exports.AiChatProvider = AiChatProvider;
|
|
89
|
+
/**
|
|
90
|
+
* Returns the AiChatContext, which includes all results from `@ai-sdk/react`'s
|
|
91
|
+
* [`useChat`](https://ai-sdk.dev/docs/reference/ai-sdk-ui/use-chat) hook as
|
|
92
|
+
* well as the initial messages.
|
|
93
|
+
*
|
|
94
|
+
* In addition to customizing the fetcher, using a context allows us to avoid
|
|
95
|
+
* this issue https://github.com/vercel/ai/issues/3266 since the caller no
|
|
96
|
+
* longer needs to provide the initial messages.
|
|
97
|
+
*/
|
|
98
|
+
const useAiChat = () => {
|
|
99
|
+
const context = React.useContext(AiChatContext);
|
|
100
|
+
if (!context) {
|
|
101
|
+
throw new Error("useAiChatContext must be used within an AiChatProvider");
|
|
102
|
+
}
|
|
103
|
+
return context;
|
|
104
|
+
};
|
|
105
|
+
exports.useAiChat = useAiChat;
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { Meta, StoryObj } from "@storybook/react";
|
|
2
|
+
import { AiChatProvider } from "./AiChatContext";
|
|
3
|
+
/**
|
|
4
|
+
* AiChatProvider provides state and functions for managing chat. The higher-level
|
|
5
|
+
* `AiChat` component is a wrapper around this provider and the `AiChatDisplay`,
|
|
6
|
+
* roughly.
|
|
7
|
+
*
|
|
8
|
+
* If you need to access chat state outside of the chat display, you can use
|
|
9
|
+
* `AiChatProvider` directly.
|
|
10
|
+
*/
|
|
11
|
+
declare const meta: Meta<typeof AiChatProvider>;
|
|
12
|
+
export default meta;
|
|
13
|
+
type Story = StoryObj<typeof AiChatProvider>;
|
|
14
|
+
export declare const StreamingResponses: Story;
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.StreamingResponses = void 0;
|
|
4
|
+
const React = require("react");
|
|
5
|
+
const AiChat_1 = require("./AiChat");
|
|
6
|
+
const AiChatContext_1 = require("./AiChatContext");
|
|
7
|
+
const styled_1 = require("@emotion/styled");
|
|
8
|
+
const api_1 = require("./test-utils/api");
|
|
9
|
+
const Typography_1 = require("@mui/material/Typography");
|
|
10
|
+
const TEST_API_STREAMING = "http://localhost:4567/streaming";
|
|
11
|
+
const INITIAL_MESSAGES = [
|
|
12
|
+
{
|
|
13
|
+
content: "Hi! What are you interested in learning about?",
|
|
14
|
+
role: "assistant",
|
|
15
|
+
},
|
|
16
|
+
];
|
|
17
|
+
const STARTERS = [
|
|
18
|
+
{ content: "I'm interested in quantum computing" },
|
|
19
|
+
{ content: "I want to understand global warming. " },
|
|
20
|
+
{ content: "I am curious about AI applications for business" },
|
|
21
|
+
];
|
|
22
|
+
const Container = styled_1.default.div({
|
|
23
|
+
width: "100%",
|
|
24
|
+
height: "400px",
|
|
25
|
+
position: "relative",
|
|
26
|
+
});
|
|
27
|
+
const MessageCounter = () => {
|
|
28
|
+
const { messages } = (0, AiChatContext_1.useAiChat)();
|
|
29
|
+
return (React.createElement(Typography_1.default, { variant: "subtitle1" },
|
|
30
|
+
"Message count: ",
|
|
31
|
+
messages.length,
|
|
32
|
+
" (Provided by ",
|
|
33
|
+
React.createElement("code", null, "AiChatContext"),
|
|
34
|
+
")"));
|
|
35
|
+
};
|
|
36
|
+
/**
|
|
37
|
+
* AiChatProvider provides state and functions for managing chat. The higher-level
|
|
38
|
+
* `AiChat` component is a wrapper around this provider and the `AiChatDisplay`,
|
|
39
|
+
* roughly.
|
|
40
|
+
*
|
|
41
|
+
* If you need to access chat state outside of the chat display, you can use
|
|
42
|
+
* `AiChatProvider` directly.
|
|
43
|
+
*/
|
|
44
|
+
const meta = {
|
|
45
|
+
title: "smoot-design/AI/AiChatContext",
|
|
46
|
+
component: AiChatContext_1.AiChatProvider,
|
|
47
|
+
parameters: {
|
|
48
|
+
msw: { handlers: api_1.handlers },
|
|
49
|
+
},
|
|
50
|
+
render: (args) => {
|
|
51
|
+
return (React.createElement(AiChatContext_1.AiChatProvider, Object.assign({}, args),
|
|
52
|
+
React.createElement(MessageCounter, null),
|
|
53
|
+
React.createElement(Container, null,
|
|
54
|
+
React.createElement(AiChat_1.AiChatDisplay, { entryScreenEnabled: false, conversationStarters: STARTERS, placeholder: "Type your message here", askTimTitle: "Ask TIM" }))));
|
|
55
|
+
},
|
|
56
|
+
decorators: (Story) => {
|
|
57
|
+
return (React.createElement(Container, null,
|
|
58
|
+
React.createElement(Story, null)));
|
|
59
|
+
},
|
|
60
|
+
args: {
|
|
61
|
+
requestOpts: { apiUrl: TEST_API_STREAMING },
|
|
62
|
+
initialMessages: INITIAL_MESSAGES,
|
|
63
|
+
},
|
|
64
|
+
argTypes: {
|
|
65
|
+
initialMessages: {
|
|
66
|
+
control: { type: "object", disable: true },
|
|
67
|
+
},
|
|
68
|
+
requestOpts: {
|
|
69
|
+
control: { type: "object", disable: true },
|
|
70
|
+
table: { readonly: true }, // See above
|
|
71
|
+
},
|
|
72
|
+
},
|
|
73
|
+
};
|
|
74
|
+
exports.default = meta;
|
|
75
|
+
exports.StreamingResponses = {};
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const React = require("react");
|
|
4
|
+
const react_markdown_1 = require("react-markdown");
|
|
5
|
+
const browser_1 = require("rehype-mathjax/browser");
|
|
6
|
+
const remark_math_1 = require("remark-math");
|
|
7
|
+
const better_react_mathjax_1 = require("better-react-mathjax");
|
|
8
|
+
const Markdown = ({ children, enableMathjax }) => {
|
|
9
|
+
const remarkPlugins = enableMathjax ? [remark_math_1.default] : undefined;
|
|
10
|
+
const rehypePlugins = enableMathjax ? [browser_1.default] : undefined;
|
|
11
|
+
const markdown = (React.createElement(react_markdown_1.default, { skipHtml: true, remarkPlugins: remarkPlugins, rehypePlugins: rehypePlugins }, children));
|
|
12
|
+
return enableMathjax ? React.createElement(better_react_mathjax_1.MathJax, null, markdown) : markdown;
|
|
13
|
+
};
|
|
14
|
+
exports.default = Markdown;
|