Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(plus): add AI Help #9098

Merged
merged 152 commits into from
Jun 19, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
152 commits
Select commit Hold shift + click to select a range
edf5556
chore(deps): add sse.js 0.6.1
caugner May 16, 2023
3af531f
chore(deps): add react-markdown 8.0.7
caugner May 16, 2023
a2036b5
chore(deps): add openai 3.2.1
caugner May 16, 2023
ce71a7d
wip
caugner May 17, 2023
c076a3c
chore: inline var
caugner May 19, 2023
ce3ed1f
chore: rename {MDN AI => Ask MDN}
caugner May 19, 2023
dbc1f34
fix: use primary border color for dialog
caugner May 19, 2023
038d418
fix: remove console.log
caugner May 19, 2023
6f98306
fixup! chore: rename {MDN AI => Ask MDN}
caugner May 19, 2023
a7424b1
fix: add missing useEffect dep
caugner May 19, 2023
f2cbc52
wip
fiji-flo May 22, 2023
476d005
chore(deps-dev): add openai 3.x
caugner May 25, 2023
e9e9064
chore(deps-dev): add @supabase/supabase-js 2.x
caugner May 25, 2023
1aebf68
feat(tool): add update-embeddings command
caugner May 25, 2023
9c23ef3
fixup! feat(tool): add update-embeddings command
caugner May 25, 2023
e22a1d4
fixup! fixup! feat(tool): add update-embeddings command
caugner May 25, 2023
724f609
chore: request embeddings concurrently
caugner May 25, 2023
01ec917
chore(embeddings): rename tables
caugner May 26, 2023
a4aedb5
chore(embeddings): rename columns
caugner May 26, 2023
f8cd75a
chore(tool): add embeddings sql
caugner May 26, 2023
bdf5a2b
fix(ask): send request with credentials
caugner May 30, 2023
cb41365
fix(ask): use finish_reason to determine end of message
caugner May 30, 2023
0ac2be1
chore(ask): differentiate loading & responding
caugner May 30, 2023
e76b5c9
chore(ask): add some MDN-related questions
caugner May 30, 2023
77c7b05
fix(search/dialog): open via button next to UserMenu
caugner May 30, 2023
f83a1d5
Merge remote-tracking branch 'origin/main' into ask-mdn
caugner May 30, 2023
2401a50
feat(ask): add close button
caugner May 30, 2023
25f0449
chore: rename "Ask MDN" to "AI Help"
caugner Jun 5, 2023
649c1c2
chore(ai-help): move to top navigation
caugner Jun 5, 2023
20c314c
feat(ai-help): rename "Ask MDN" to "AI Help" and move to page
caugner Jun 5, 2023
1fa9ac8
chore(ai-help): highlight assistant messages
caugner Jun 5, 2023
f060799
feat(ai-help): use avatar + chatgpt logo
caugner Jun 5, 2023
fba61c3
fix(ai-help): align avatar with text
caugner Jun 5, 2023
ec875db
feat(ai-help): use green color scheme
caugner Jun 5, 2023
f2cf83e
fix(ai-help): use same color for header + body links
caugner Jun 5, 2023
80e5b5f
fix(ai-help): underline links on hover
caugner Jun 5, 2023
80c4d12
Merge remote-tracking branch 'origin/main' into ask-mdn
caugner Jun 9, 2023
67fd3a8
fix(ai-help): use relative URL
caugner Jun 12, 2023
a31d48e
fix(ai-help): apply document list style
caugner Jun 12, 2023
59a92f9
chore(ai-help): add blinking cursor
caugner Jun 12, 2023
5120fbb
chore(ai-help): use rounded corners
caugner Jun 12, 2023
58c07f7
chore(ai-help): add footer with Supabase/OpenAI mention
caugner Jun 12, 2023
304322f
feat(ai-help): display quota in input placeholder
caugner Jun 12, 2023
7aa6b9b
Merge remote-tracking branch 'origin/main' into ask-mdn
caugner Jun 12, 2023
524f4f8
feat(ai-help): add send button …
caugner Jun 12, 2023
bb93728
fixup! chore(ai-help): add blinking cursor
caugner Jun 12, 2023
1c8d4dc
chore(ai-help): reduce to 3 questions
caugner Jun 12, 2023
68552d3
fix(ai-help): add container padding
caugner Jun 12, 2023
57029c5
m chore(ai-help): optimise send icon
caugner Jun 12, 2023
b67f001
chore(ai-help): resize input field
caugner Jun 12, 2023
c5d2578
chore(ai-help): remove unnecessary flex/overflow
caugner Jun 12, 2023
2ef1e4e
chore(thumbs): show question/confirmation conditionally
caugner Jun 12, 2023
89341b9
feat(ai-help): show thumbs on answers
caugner Jun 12, 2023
9a8057a
fixup! feat(ai-help): add send button …
caugner Jun 12, 2023
ae4aaf3
chore(ai-help): update footer + left align
caugner Jun 13, 2023
0e2951a
fix(ai-help): avoid input overlap with send icon
caugner Jun 13, 2023
b70a20b
chore(ai-help): update loading placeholder copies
caugner Jun 13, 2023
0b49d16
fix(ai-help): always show thumbs on completed answer
caugner Jun 13, 2023
1c89c7a
Merge branch 'ask-mdn-embeddings' into ask-mdn
caugner Jun 13, 2023
e7f907b
chore(update-embeddings): add title
caugner Jun 13, 2023
1f1494b
chore(ai-help): show error properly above input field
caugner Jun 13, 2023
de6fecf
fix(thumbs): set height = 1.5rem in general
caugner Jun 13, 2023
bab9cac
chore(thumbs): use icon-secondary color for icons
caugner Jun 13, 2023
a2fa77d
fix(ai-help): make content span full width
caugner Jun 13, 2023
44ef2a5
chore(ai-help): add margin between input + footer
caugner Jun 13, 2023
60ac210
feat(ai-help): display answer source
caugner Jun 13, 2023
1dfee26
chore(ai-help): title is now never null
caugner Jun 13, 2023
29dc6e3
chore(ai-help): update metadata event
caugner Jun 13, 2023
16dfa63
feat(ai-help): use quota returned from API
caugner Jun 13, 2023
681232f
fix(ai-help): add key for loop components
caugner Jun 13, 2023
2d53927
chore(ai-help): update API path
caugner Jun 13, 2023
ca43122
chore(ai-help): remove unnecessary CSS for .ai-help-inner
caugner Jun 13, 2023
108f543
feat(ai-help): make first message sticky
caugner Jun 13, 2023
fbdfdda
feat(ai-help): add "New chat" button
caugner Jun 13, 2023
25fb2e4
feat(ai-help): fetch quota on load
caugner Jun 13, 2023
afef151
fix(ai-help): reset input on submit
caugner Jun 13, 2023
71a8b2d
chore(ai-help): show Loader until we have quota
caugner Jun 13, 2023
298e527
feat(ai-help): add upsell banner
caugner Jun 14, 2023
0997ef0
Merge remote-tracking branch 'origin/main' into ask-mdn
caugner Jun 14, 2023
0674848
chore(ai-help): update sources section copy
caugner Jun 14, 2023
524c7dd
fix(ai-help): reduce z-index of sticky question
caugner Jun 14, 2023
0a219b8
chore(ai-help): update sources section copy
caugner Jun 14, 2023
48d74f5
chore(ai-help): update footer copy
caugner Jun 14, 2023
f928879
feat(ai-help): persist current chat
caugner Jun 14, 2023
6b62c2f
fix(ai-help): replace fallback + hide sources in this case
caugner Jun 14, 2023
997478d
feat(ai-help): add stop button
caugner Jun 14, 2023
6b2d4ee
chore(ai-help): show ellipsis on stopped message
caugner Jun 14, 2023
a4141ab
fix(ai-help): pluralize remaining questions, remove isPlusSubscriber …
caugner Jun 14, 2023
2c79507
fix(ai-help): add missing effect dep
caugner Jun 14, 2023
a8b2e7d
chore(ai-help): update JavaScript question
caugner Jun 14, 2023
a550495
fix(ai-help): fix example url
caugner Jun 14, 2023
6d2a602
chore(ai-help): update upsell copy
caugner Jun 14, 2023
5534db8
feat(ai-help): show examples below + don't submit directly
caugner Jun 14, 2023
8ea0f5f
fix(ai-help): hide sources sections if we do not have sources
caugner Jun 14, 2023
8a05af9
feat(ai-help): move examples below + categorize + apply Updates design
caugner Jun 14, 2023
c6cae28
feat(ai-help): make footer sticky
caugner Jun 14, 2023
6328665
chore(ai-help): move stop button to actions
caugner Jun 14, 2023
d12d530
fix(ai-help): scroll to top with timeout
caugner Jun 14, 2023
f414903
chore(ai-help): rename role-* CSS class + restructure CSS
caugner Jun 14, 2023
b5b692f
refactor(ai-help): move status CSS class to message container
caugner Jun 14, 2023
1fb67d1
chore(ai-help): move stop button back to footer
caugner Jun 14, 2023
683a531
chore(ai-help): show stop while loading
caugner Jun 14, 2023
ddbe49f
feat(ai-help): scroll automatically until user scrolls
caugner Jun 14, 2023
7e0a40d
fix(ai-help): make auto-scroll reliable
caugner Jun 14, 2023
1697ed4
feat(ai-help): add "Enable auto-scroll" button
caugner Jun 14, 2023
7c96c01
fix(ai-help): scroll after render
caugner Jun 14, 2023
b9db146
fix(ai-help): scroll + focus when selecting example
caugner Jun 14, 2023
3ff7461
chore(ai-help): use accent color for examples
caugner Jun 14, 2023
8561738
chore(ai-help): use border-primary for examples
caugner Jun 15, 2023
96724fd
fix(ai-help): update input focus style
caugner Jun 15, 2023
acd1c57
chore(placement): update fallback top banner
caugner Jun 15, 2023
baf1b0e
feat(ai-help): add to offer overview
caugner Jun 15, 2023
a838428
feat(server): proxy /api/v1/stripe/plans to stage API
caugner Jun 15, 2023
a062886
chore(ai-help): add to plan details
caugner Jun 15, 2023
311bdf7
chore: revert obsolete code from earlier version
caugner Jun 15, 2023
5f5e320
Merge remote-tracking branch 'origin/main' into ai-help
caugner Jun 15, 2023
2dc6021
fixup! chore(ai-help): add to plan details
caugner Jun 15, 2023
53a2a65
chore(offer-overview): remove "new" pill from "Ads free"
caugner Jun 15, 2023
2503338
feat(plus-menu): add AI Help entry
caugner Jun 15, 2023
fe93f76
fix(ai-help): store messages only when not loading/receiving
caugner Jun 15, 2023
6e836a6
chore(ai-help): make input span full width
caugner Jun 15, 2023
60a6426
chore(ai-help): refine source section copy
caugner Jun 15, 2023
bc37501
fix(ai-help): determine quota states correctly
caugner Jun 15, 2023
b2c7d6d
chore(ai-help): disable "New chat" if quota exceeded
caugner Jun 15, 2023
c8d51b0
feat(ai-help): focus input automatically
caugner Jun 15, 2023
d2c7c91
chore(ai-help): update GPT 3.5 -> GPT-3.5
caugner Jun 15, 2023
33160cb
refactor(ai-help): improve input CSS
caugner Jun 15, 2023
0727666
fix(ai-help): position send button properly
caugner Jun 15, 2023
f9b8a41
fix(ai-help): reset isLoading on stop
caugner Jun 15, 2023
74b9cd3
chore(ai-help): refine placeholder
caugner Jun 15, 2023
9c9ea14
feat(ai-help): add "Upgrade now" button to upsell banner
caugner Jun 15, 2023
eefcaeb
refactor(ai-help): extract resetState()
caugner Jun 16, 2023
9e1eb51
refactor(ai-help): extract handleMessageData()
caugner Jun 16, 2023
5258004
feat(ai-help): collect raw data
caugner Jun 16, 2023
d6ca7aa
chore(ai-help): disable auto-scroll
caugner Jun 16, 2023
1ca215c
fixup! refactor(ai-help): extract handleMessageData()
caugner Jun 16, 2023
9af28ff
Revert "chore(ai-help): disable auto-scroll"
caugner Jun 16, 2023
bdb5c4b
Merge branch 'main' into ai-help
caugner Jun 16, 2023
b1358fd
style: run stylelint fix
caugner Jun 16, 2023
197d139
fix(ai-help): avoid mutating state in reducer
caugner Jun 19, 2023
7df4ff0
chore(ai-help): throw when dispatch event refers to missing message
caugner Jun 19, 2023
07dfb06
fix(ai-help): reset message-index
caugner Jun 19, 2023
c3c3630
fix(ai-help): avoid reading localStorage on every render
caugner Jun 19, 2023
6624b84
chore(ai-help): hide raw output behind #debug hash
caugner Jun 19, 2023
bb95a3e
chore(ai-help): show example category colors on hover
caugner Jun 19, 2023
806f126
fix(ai-help): pass body/footer as refs to useAutoScroll()
caugner Jun 19, 2023
3ed14fd
feat(ai-help): mark external links with icon
caugner Jun 19, 2023
a034d20
chore(ai-help): remove status class from content
caugner Jun 19, 2023
636d93f
fixup! fix(ai-help): pass body/footer as refs to useAutoScroll()
caugner Jun 19, 2023
0b37593
fix(ai-help): add missing effect dependency
caugner Jun 19, 2023
6362356
chore(ai-help): add 0.5rem button padding
caugner Jun 19, 2023
d4edcd5
Revert "chore(ai-help): show example category colors on hover"
caugner Jun 19, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions build/spas.ts
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,11 @@ export async function buildSPAs(options: {
const SPAs = [
{ prefix: "search", pageTitle: "Search" },
{ prefix: "plus", pageTitle: MDN_PLUS_TITLE },
{
prefix: "plus/ai-help",
pageTitle: `AI Help | ${MDN_PLUS_TITLE}`,
noIndexing: true,
},
{
prefix: "plus/collections",
pageTitle: `Collections | ${MDN_PLUS_TITLE}`,
Expand Down
Binary file added client/public/assets/ai-help.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
5 changes: 5 additions & 0 deletions client/src/assets/icons/chatgpt.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
5 changes: 5 additions & 0 deletions client/src/assets/icons/send.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions client/src/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,5 @@ export { MDN_PLUS_TITLE, VALID_LOCALES } from "../../libs/constants";
export enum FeatureId {
PLUS_UPDATES_V2 = "plus_updates_v2",
PLUS_NEWSLETTER = "plus_newsletter",
PLUS_AI_HELP = "plus_ai_help",
}
1 change: 0 additions & 1 deletion client/src/document/organisms/sidebar/filter.scss
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,6 @@

.glean-thumbs {
font-size: var(--type-tiny-font-size);
height: 1.5rem;
margin-bottom: 0.5rem;
margin-left: 0.6rem;
}
Expand Down
330 changes: 330 additions & 0 deletions client/src/plus/ai-help/index.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,330 @@
@use "../../ui/vars" as *;

.ai-help {
--category-color: var(--ai-help-icon);
--text-link: var(--ai-help-link);

> header {
--plus-header: var(--ai-help-header);
--plus-mandala: var(--ai-help-mandala);
--plus-icon: var(--ai-help-icon);
--plus-link: var(--ai-help-link);
}

> .container {
padding: var(--gutter);
}

button.button[disabled],
input[disabled] {
cursor: not-allowed;
}

a:hover {
text-decoration: underline;
}

.ai-help-inner {
.ai-help-body,
.ai-help-footer {
padding: 0.5rem 0;
}

.ai-help-footer {
background-color: var(--background-primary);
bottom: 0;
mask-image: linear-gradient(
to top,
rgb(0, 0, 0) 0% calc(100% - 0.5rem),
rgba(0, 0, 0, 0) 100%
);
padding-top: 1rem;
position: sticky;

.ai-help-footer-actions {
padding-bottom: 0.5rem;
}

.ai-help-footer-text {
font-size: var(--type-tiny-font-size);
margin-left: calc(1px + 1rem); /* Border + padding */
margin-top: 0.5rem;
}
}

.ai-help-input-form {
--form-elem-height: 3rem;
position: relative;
width: 100%;

input {
background-color: var(--background-primary);
border: 1px solid var(--border-primary);
border-radius: 100px;
color: var(--text-primary);
height: var(--form-elem-height);
padding-left: 1rem;
padding-right: 3rem;
width: 100%;

&:focus {
border-color: var(--category-color);
box-shadow: 0 0 0 3px var(--blend-color),
0 0 0 3px var(--category-color);
outline: 0 none;
}
}

button {
--button-color: var(--icon-secondary);
--button-height: 2.5rem;
--button-padding: 0.5rem;
--icon-size: 1.5rem;

display: block;
position: absolute;
right: calc(0.5rem + 1px);
top: 0.25rem;

&:hover {
background: transparent;
}
}
}

&.has-input {
button {
--button-color: var(--ai-help-icon);
}
}

.ai-help-examples {
background: var(--background-secondary);
border-radius: 0.25rem;
display: flex;
flex-direction: column;
gap: 1rem;
margin: 1rem 0;
padding: 1rem;

header {
font-weight: 500;
letter-spacing: var(--header-letter-spacing);
line-height: 175%;
}
}

.ai-help-example {
--category-color-engage: var(--border-primary);
background: var(--background-primary);
border-radius: 0.25rem;
box-shadow: inset 0.25rem 0 0 var(--category-color-engage);
cursor: pointer;
font-size: var(--type-smaller-font-size);
padding: 0.5rem 1rem;
text-align: left;

&:hover {
color: var(--ai-help-link);
}
}

.ai-help-messages {
display: flex;
flex-direction: column;
gap: 1rem;
}

.ai-help-message {
border: 1px solid transparent;
display: flex;
padding: 1rem;

&:first-of-type {
background-color: var(--background-primary);
mask-image: linear-gradient(
to bottom,
rgb(0, 0, 0) 0% calc(100% - 0.5rem),
rgba(0, 0, 0, 0) 100%
);
position: sticky;
top: calc(var(--top-nav-height) + 1px);
z-index: var(--z-index-nav-menu);

.ai-help-actions {
white-space: nowrap;
}
}

&.role-user {
color: var(--text-secondary);

.avatar-wrap {
border-radius: unset;
height: 1.5rem;
margin-left: unset;
margin-right: unset;
margin-top: 0.1rem; /* Align with text. */
position: unset;
width: 1.5rem;
}
}

&.role-assistant {
background-color: var(--background-secondary);
border: 1px solid var(--border-primary);
border-radius: var(--elem-radius);

.ai-help-message-role {
--icon-size: 1.5rem;
}
}

.ai-help-message-role {
flex-shrink: 0;
width: 2.5rem;
}

.glean-thumbs {
font-size: var(--type-tiny-font-size);
justify-content: flex-end;
}

&.status-pending .ai-help-message-content,
&.status-in-progress .ai-help-message-content {
&.empty::after,
> :not(ol):not(ul):not(pre):last-child:after,
> ol:last-child li:last-child:after,
> pre:last-child code:after,
> ul:last-child li:last-child:after {
animation: blink 1s steps(5, start) infinite;
content: "▋";
margin-left: 0.25rem;
vertical-align: baseline;

@keyframes blink {
to {
visibility: hidden;
}
}
}

&.empty::after {
margin-left: unset;
}
}

&.status-stopped .ai-help-message-content {
&.empty::after,
> :not(ol):not(ul):not(pre):last-child:after,
> ol:last-child li:last-child:after,
> pre:last-child code:after,
> ul:last-child li:last-child:after {
content: "…";
margin-left: 0.25rem;
vertical-align: baseline;
}

&.empty::after {
margin-left: unset;
}
}
}

.ai-help-message-content {
width: 100%;

p {
margin: 1rem 0;

&:first-child {
margin-top: 0;
}

&:last-child {
margin-bottom: 0;
}
}

ul,
ol {
margin: 1rem 0 2rem;
padding-left: 2rem;

li {
margin: 0.5rem 0;
}
}

ul {
list-style: disc;

ul {
list-style-type: circle;
margin: 0;
padding-left: 1rem;
}
}

ol {
list-style: decimal;

ol {
list-style: lower-roman;
margin: 0;
}
}

dd ol,
dd ul {
margin-bottom: 1rem;
padding-left: 3rem;
}

td ul,
td ol {
padding-left: 1rem;
}

dd li {
margin-bottom: 1rem;
}

td li {
margin-bottom: 0.5rem;
}

dl {
dt {
margin-bottom: 0.5rem;
margin-top: 2rem;
}

dd {
margin-bottom: 1rem;
margin-left: 1rem;

.notecard {
p {
padding-left: 0;
}
}
}

p {
margin: 0 0 1rem;
}
}
}

.ai-help-footer-actions {
display: flex;
gap: 1rem;
justify-content: center;
}

.ai-help-error {
margin: 0.5rem 0;
}
}
}
Loading