AI Responses now handle Markdown

This commit is contained in:
Chris Kent 2024-02-08 12:10:49 -05:00
parent f4dcbfe26c
commit 8b0388beda
8 changed files with 4457 additions and 11 deletions

View File

@ -44,13 +44,15 @@ This sample is optimally compatible with the following environment configuration
## Contributors ## Contributors
- [Luis Mañez](https://github.com/luismanez) | - [Luis Mañez](https://github.com/luismanez)
- [Chris Kent](https://twitter.com/thechriskent)
## Version history ## Version history
| Version | Date | Comments | | Version | Date | Comments |
| ------- | ---------------- | --------------- | | ------- | ---------------- | --------------- |
| 1.0 | January 2, 2024 | Initial release | | 1.0 | January 2, 2024 | Initial release |
| 1.1 | January 29, 2024 | Things and Stuff |
## Minimal Path to Awesome ## Minimal Path to Awesome

View File

@ -13,4 +13,10 @@ build.rig.getTasks = function () {
return result; return result;
}; };
/* fast-serve */
const { addFastServe } = require("spfx-fast-serve-helpers");
addFastServe(build);
/* end of fast-serve */
build.initialize(require('gulp')); build.initialize(require('gulp'));

File diff suppressed because it is too large Load Diff

View File

@ -9,7 +9,8 @@
"scripts": { "scripts": {
"build": "gulp bundle", "build": "gulp bundle",
"clean": "gulp clean", "clean": "gulp clean",
"test": "gulp test" "test": "gulp test",
"serve": "fast-serve"
}, },
"dependencies": { "dependencies": {
"@fluentui/react": "^8.106.4", "@fluentui/react": "^8.106.4",
@ -25,6 +26,8 @@
"@pnp/spfx-property-controls": "3.15.1", "@pnp/spfx-property-controls": "3.15.1",
"react": "17.0.1", "react": "17.0.1",
"react-dom": "17.0.1", "react-dom": "17.0.1",
"react-remark": "^2.1.0",
"remark-gfm": "1.0.0",
"tslib": "2.3.1" "tslib": "2.3.1"
}, },
"devDependencies": { "devDependencies": {
@ -41,6 +44,7 @@
"eslint": "8.7.0", "eslint": "8.7.0",
"eslint-plugin-react-hooks": "4.3.0", "eslint-plugin-react-hooks": "4.3.0",
"gulp": "4.0.2", "gulp": "4.0.2",
"spfx-fast-serve-helpers": "~1.18.0",
"typescript": "4.7.4" "typescript": "4.7.4"
} }
} }

View File

@ -2,6 +2,7 @@ import { Stack } from "@fluentui/react";
import { Icon } from '@fluentui/react'; import { Icon } from '@fluentui/react';
import * as React from "react"; import * as React from "react";
import styles from "./ChatStreaming.module.scss"; import styles from "./ChatStreaming.module.scss";
import MarkdownContent from "./MarkdownContent";
export interface IAssistantResponseProps { export interface IAssistantResponseProps {
message: string; message: string;
@ -18,7 +19,7 @@ export default class AssistantResponse extends React.Component<
<Icon iconName="Robot" /> <Icon iconName="Robot" />
</div> </div>
<div className={styles.messageBox}> <div className={styles.messageBox}>
<p className={styles.message}>{this.props.message}</p> <MarkdownContent className={styles.message}>{this.props.message}</MarkdownContent>
<div className={styles.beak}/> <div className={styles.beak}/>
</div> </div>
</Stack> </Stack>

View File

@ -67,6 +67,10 @@
justify-content: center; justify-content: center;
} }
.message {
margin: 14px 0;
}
.beak { .beak {
left: -15px; left: -15px;
border-right: 15px solid "[theme:white, default: #ffffff]"; border-right: 15px solid "[theme:white, default: #ffffff]";
@ -103,4 +107,45 @@
.userMessage { .userMessage {
gap: 5px; gap: 5px;
}
.markdownContent {
table {
border-spacing: 0;
border-collapse: collapse;
display: block;
margin: 14px 0;
width: max-content;
max-width: fit-content;
overflow: auto;
}
tr {
background-color: "[theme: white, default: #ffffff]";
border-top: 1px solid "[theme: neutralTertiaryAlt, default: #c8c6c4]";
}
tr:nth-child(2n) {
background-color: "[theme: neutralLight, default: #edebe9]";
}
td,
th {
padding: 6px 13px;
border: 1px solid "[theme: neutralTertiaryAlt, default: #c8c6c4]";
}
th {
font-weight: 600;
}
table img {
background-color: transparent;
}
pre {
background-color: "[theme: neutralLight, default: #edebe9]";
padding: 8px;
border-radius: 4px;
}
} }

View File

@ -0,0 +1,23 @@
import { css } from "@fluentui/react";
import * as React from "react";
import styles from "./ChatStreaming.module.scss";
import { Remark } from "react-remark";
import remarkGfm from "remark-gfm";
export interface IMarkdownContentProps {
children: string;
className?: string;
}
export default class MarkdownContent extends React.Component<
IMarkdownContentProps,
{}
> {
public render(): React.ReactElement<IMarkdownContentProps> {
return (
<div className={css(styles.markdownContent, this.props.className)}>
<Remark remarkPlugins={[remarkGfm]}>{this.props.children}</Remark>
</div>
);
}
}

View File

@ -13,6 +13,7 @@
"outDir": "lib", "outDir": "lib",
"inlineSources": false, "inlineSources": false,
"noImplicitAny": true, "noImplicitAny": true,
"allowSyntheticDefaultImports": true,
"typeRoots": [ "typeRoots": [
"./node_modules/@types", "./node_modules/@types",