-
Notifications
You must be signed in to change notification settings - Fork 77
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
This PR adds `MdxChatCompletion`, which produces MDX output as a string. It does not handle: * Auto-healing partial MDX (related: micromark/micromark-extension-mdx-jsx#10) * Rendering to the UI I agree with @zkoch that this also might not be the final API we want. I added docs for this, but as a standalone, this feature isn't super interesting – it gets fun when we're actually able to render to the UI. That can be a follow-up. To verify that I didn't break the previous `UICompletion` component, I manually tested the nextjs demo at http://localhost:3000/recipe.
- Loading branch information
1 parent
12cd384
commit 68adddd
Showing
11 changed files
with
487 additions
and
87 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,9 +1,10 @@ | ||
.pnp* | ||
.yarn* | ||
.vscode* | ||
*data* | ||
packages/examples/src/bakeoff/*/data/* | ||
dist | ||
.next | ||
.docusaurus | ||
*build* | ||
packages/docs/docs/api | ||
packages/docs/build | ||
packages/create-react-app-demo/build/ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,115 @@ | ||
import * as AI from '../core.js'; | ||
import { ChatCompletion, SystemMessage } from '../../core/completion.js'; | ||
import React from 'react'; | ||
import { collectComponents } from '../completion.js'; | ||
|
||
/** | ||
* Use GPT-4 with this. | ||
*/ | ||
export function MdxChatCompletion({ children, usageExamples }: { children: AI.Node; usageExamples: React.ReactNode }) { | ||
const components = collectComponents(usageExamples); | ||
/* prettier-ignore */ | ||
return <ChatCompletion> | ||
<SystemMessage> | ||
You are an assistant who can use React components to work with the user. By default, you use markdown. However, if it's useful, you can also mix in the following React components: {Object.keys(components).join(', ')}. | ||
All your responses | ||
should be in MDX, which is Markdown For the Component Era. Here are instructions for how to use MDX: | ||
=== Begin instructions | ||
{/* Snipped from https://github.com/mdx-js/mdx/blob/main/docs/docs/what-is-mdx.server.mdx. */} | ||
MDX allows you to use JSX in your markdown content. | ||
You can import components, such as interactive charts or alerts, and embed them | ||
within your content. | ||
This makes writing long-form content with components a blast. | ||
|
||
More practically MDX can be explained as a format that combines markdown with | ||
JSX and looks as follows: | ||
|
||
=== Begin example | ||
{` | ||
Here is some markdown text | ||
<MyComponent id="123" /> | ||
# Here is more markdown text | ||
<Component | ||
open | ||
x={1} | ||
label={'this is a string, *not* markdown!'} | ||
icon={<Icon />} | ||
/> | ||
* Markdown list item 1 | ||
* Markdown list item 2 | ||
* Markdown list item 3 | ||
`} | ||
=== end example | ||
=== end instructions | ||
|
||
Do not include a starting ```mdx and closing ``` line. Just respond with the MDX itself. | ||
|
||
Do not include extra whitespace that is not needed for the markdown interpretation. For instance, if your component has a prop that's a JSON object, put it all on one line: | ||
|
||
{'<Component prop={[[{"key": "value"}, {"long": "field"}]]} />'} | ||
|
||
This doc tells you the differences between MDX and markdown. | ||
|
||
{/* Adapted from https://github.com/micromark/mdx-state-machine#72-deviations-from-markdown */} | ||
=== Start doc | ||
### 7.2 Deviations from Markdown | ||
|
||
MDX adds constructs to Markdown but also prohibits certain normal Markdown | ||
constructs. | ||
|
||
#### 7.2.2 Indented code | ||
|
||
Indentation to create code blocks is not supported. | ||
Instead, use fenced code blocks. | ||
|
||
The reason for this change is so that elements can be indented. | ||
|
||
{/* Commenting out the negative examples because they seem to confuse the LLM. */} | ||
{/* | ||
Incorrect: | ||
```markdown | ||
console.log(1) | ||
``` */} | ||
|
||
Correct: | ||
|
||
```js | ||
console.log(1) | ||
``` | ||
|
||
#### 7.2.3 Autolinks | ||
|
||
Autolinks are not supported. | ||
Instead, use links or references. | ||
|
||
The reason for this change is because whether something is an element (whether | ||
HTML or JSX) or an autolink is ambiguous {'(Markdown normally treats `<svg:rect>`, `<xml:lang/>`, or `<svg:circle{...props}>` as links).'} | ||
|
||
{/* Incorrect: | ||
```markdown | ||
See <https://example.com> for more information | ||
``` */} | ||
|
||
Correct: | ||
|
||
See [example.com](https://example.com) for more information. | ||
|
||
#### 7.2.4 Errors | ||
|
||
Whereas all Markdown is valid, incorrect MDX will crash. | ||
=== end doc | ||
|
||
Here are the components you have available, and how to use them: | ||
|
||
=== Begin components | ||
<AI.React>{usageExamples}</AI.React> | ||
=== end components | ||
</SystemMessage> | ||
{children} | ||
</ChatCompletion>; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,81 @@ | ||
# MDX Output | ||
|
||
By default, models emit text. If you ask them to, they'll emit markdown, which is a robust, easy way to provide more structured output to your user. | ||
|
||
To take it a step further, you can have the model emit [MDX](https://mdxjs.com/), which combines Markdown and your components: | ||
|
||
```mdx | ||
# Last year’s snowfall | ||
|
||
In {year}, the snowfall was above average. | ||
It was followed by a warm spring which caused | ||
flood conditions in many of the nearby rivers. | ||
|
||
<Chart year={year} color="#fcb32c" /> | ||
``` | ||
|
||
To do this, use the `MdxChatCompletion` component: | ||
|
||
```tsx | ||
<MdxChatCompletion usageExamples={usageExample}> | ||
<UserMessage>Tell me a children's story. Summarize the key characters at the end.</UserMessage> | ||
</MdxChatCompletion> | ||
``` | ||
|
||
[(See the examples project for a full working demo.)](https://github.com/fixie-ai/ai-jsx/blob/main/packages/examples/src/mdx.tsx) | ||
|
||
## Telling the model which components are available | ||
|
||
The API for `MdxChatCompletion` is the same as `ChatCompletion`, except it adds a `usageExamples` prop. That prop is an AI.JSX component that tells the model which components are available: | ||
|
||
<!-- prettier-ignore --> | ||
```tsx | ||
const usageExample = ( | ||
<> | ||
Use a Card to display collected information to the user. The children can be markdown. Only use the card if you have | ||
a logically-grouped set of information to show the user, in the context of a larger response. Generally, your entire | ||
response should not be a card. A card takes optional header and footer props. | ||
|
||
Example 1 of how you might use this | ||
component: Here's the best candidate I found: | ||
<Card header="Sam Smith"> | ||
**Skills**: React, TypeScript, Node.js **Location**: Seattle, WA **Years of experience**: 5 **Availability**: | ||
Full-time | ||
</Card> | ||
{/* ... you may wish to add more examples */} | ||
</> | ||
); | ||
|
||
<MdxChatCompletion usageExamples={usageExample}> | ||
<UserMessage>Tell me a children's story. Summarize the key characters at the end.</UserMessage> | ||
</MdxChatCompletion> | ||
``` | ||
|
||
In that example, `Card` may refer to a real component in scope, or you can just write it out as a string: | ||
|
||
<!-- prettier-ignore --> | ||
```tsx | ||
function Card({ header, footer, children }) { | ||
return ( | ||
<div> | ||
<div className="header">{header}</div> | ||
<div className="content">{children}</div> | ||
<div className="footer">{footer}</div> | ||
</div> | ||
); | ||
} | ||
|
||
const usageExample = ( | ||
<> | ||
{/* Reference a component in scope */} | ||
Here's how you use a Card: <Card>content</Card> | ||
|
||
{/* Just write out a string */} | ||
You can also use a ButtonGroup: {`<ButtonGroup labels=['Yes', 'No'] />`} | ||
</> | ||
); | ||
``` | ||
|
||
## Using the output | ||
|
||
The output will be MDX, as a string. It will not have any import statements. If you want to render it into your UI, it's up to you to parse/compile it in some way, using the [MDX APIs](https://mdxjs.com/). |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
68adddd
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Successfully deployed to the following URLs:
ai-jsx-docs – ./packages/docs
ai-jsx-docs-fixie-ai.vercel.app
ai-jsx-docs.vercel.app
ai-jsx-docs-git-main-fixie-ai.vercel.app
docs.ai-jsx.com
68adddd
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Successfully deployed to the following URLs:
ai-jsx-nextjs-demo – ./packages/nextjs-demo
ai-jsx-nextjs-demo-git-main-fixie-ai.vercel.app
ai-jsx-nextjs-demo-fixie-ai.vercel.app
ai-jsx-nextjs-demo.vercel.app
68adddd
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Successfully deployed to the following URLs:
ai-jsx-tutorial-nextjs – ./packages/tutorial-nextjs
ai-jsx-tutorial-nextjs-fixie-ai.vercel.app
ai-jsx-tutorial-nextjs-git-main-fixie-ai.vercel.app
ai-jsx-tutorial-nextjs.vercel.app