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

AI-generated descriptions #521

Merged
merged 5 commits into from
Oct 5, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ const css = cssBinder(ipro, local, fonts);
const ImportedTag = ({ accession }: { accession: string }) => {
return (
<Tooltip
title={`The member database didn't provide a description for this signature.
title={`The member database didn't provide a description for this signature.
The description displayed has been imported from ${accession}, the InterPro entry in which the signature is integrated.`}
>
<span className={css('tag')}>
Expand Down Expand Up @@ -57,6 +57,7 @@ const ImportedTag = ({ accession }: { accession: string }) => {
type Props = {
integrated: string | null;
setIntegratedCitations?: (citations: string[]) => void;
headerText?: string;
};

interface IntegratedProps
Expand All @@ -67,6 +68,7 @@ const DescriptionFromIntegrated = ({
integrated,
data,
setIntegratedCitations = (_: string[]) => null,
headerText,
}: IntegratedProps) => {
const { loading, payload } = data || {};
useEffect(() => {
Expand All @@ -87,7 +89,7 @@ const DescriptionFromIntegrated = ({
return (
<>
<h4>
Description <ImportedTag accession={integrated} />
{headerText || 'Description'} <ImportedTag accession={integrated} />
</h4>
<Description
textBlocks={payload.metadata.description}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`<DescriptionLLM /> should render 1`] = `
<React.Fragment>
<div
className="row"
>
<div
className="columns large-12"
>
<div
className="callout warning"
style={
{
"alignItems": "center",
"display": "flex",
}
}
>
<span
className="small icon icon-common icon-exclamation-triangle"
style={
{
"color": "#664d03",
"fontSize": "2em",
"paddingRight": "1rem",
}
}
/>

<p>
<strong>
Unreviewed Protein Family Description
</strong>
<br />
This description has been automatically generated using

<Memo(Connect(Link))
className="ext"
href="https://openai.com/research/gpt-4"
target="_blank"
>
GPT-4
</Memo(Connect(Link))>
, an AI language model, and has not undergone a thorough review by curators.
<br />
Please exercise discretion when interpreting the information provided and consider it as preliminary.
</p>
</div>
</div>
</div>
<Description
textBlocks={
[
"<p>The function of the family is not clear.</p>",
]
}
/>
</React.Fragment>
`;
71 changes: 71 additions & 0 deletions src/components/Description/DescriptionLLM/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
import React, { PureComponent } from 'react';

import cssBinder from 'styles/cssBinder';
import globalStyles from 'styles/interpro-vf.css';
import fonts from 'EBI-Icon-fonts/fonts.css';
import Link from 'components/generic/Link';

import Description from '..';

const css = cssBinder(globalStyles, fonts);

type Props = {
text: string;
};

class DescriptionLLM extends PureComponent<Props> {
render() {
const text = this.props.text || '';
if (text.length === 0) return null;

return (
<>
<div className={css('row')}>
<div className={css('columns', 'large-12')}>
<div
className={css('callout', 'warning')}
style={{
display: 'flex',
alignItems: 'center',
}}
>
<span
style={{
fontSize: '2em',
color: '#664d03',
paddingRight: '1rem',
}}
className={css(
'small',
'icon',
'icon-common',
'icon-exclamation-triangle'
)}
/>{' '}
<p>
<strong>Unreviewed Protein Family Description</strong>
<br />
This description has been automatically generated using{' '}
<Link
href="https://openai.com/research/gpt-4"
className={css('ext')}
target="_blank"
>
GPT-4
</Link>
, an AI language model, and has not undergone a thorough review
by curators.
<br />
Please exercise discretion when interpreting the information
provided and consider it as preliminary.
</p>
</div>
</div>
</div>
<Description textBlocks={[text]} />
</>
);
}
}

export default DescriptionLLM;
14 changes: 14 additions & 0 deletions src/components/Description/DescriptionLLM/test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import React from 'react';
import ShallowRenderer from 'react-test-renderer/shallow';

import DescriptionLLM from '.';

const renderer = new ShallowRenderer();
const description = '<p>The function of the family is not clear.</p>';

describe('<DescriptionLLM />', () => {
test('should render', () => {
renderer.render(<DescriptionLLM text={description} />);
expect(renderer.getRenderOutput()).toMatchSnapshot();
});
});
56 changes: 35 additions & 21 deletions src/components/Entry/Summary/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import React, { useState, useEffect } from 'react';
import GoTerms from 'components/GoTerms';
import Description from 'components/Description';
import DescriptionFromIntegrated from 'components/Description/DescriptionFromIntegrated';
import DescriptionLLM from 'components/Description/DescriptionLLM';
import Literature, {
getLiteratureIdsFromDescription,
splitCitations,
Expand Down Expand Up @@ -79,7 +80,7 @@ type SummaryEntryProps = {

const SummaryEntry = ({
data: { metadata },
headerText = 'Description',
headerText,
dbInfo,
loading,
}: SummaryEntryProps) => {
Expand All @@ -101,6 +102,38 @@ const SummaryEntry = ({
(included as Array<[string, Reference]>).sort(
(a, b) => desc.indexOf(a[0]) - desc.indexOf(b[0])
);

const selectDescriptionComponent = () => {
if ((metadata.description || []).length) {
return (
<>
<h4>{headerText || 'Description'}</h4>
<Description
textBlocks={metadata.description}
literature={included as Array<[string, Reference]>}
accession={metadata.accession}
/>
</>
);
} else if (metadata.integrated) {
return (
<DescriptionFromIntegrated
integrated={metadata.integrated}
setIntegratedCitations={setIntegratedCitations}
headerText={headerText || 'Description'}
/>
);
} else if (metadata.llm_description) {
return (
<>
<h4>{headerText || 'Description'}</h4>
<DescriptionLLM text={metadata.llm_description} />
</>
);
}
return null;
};

return (
<div className={css('vf-stack', 'vf-stack--400')}>
<section className={css('vf-grid', 'summary-grid')}>
Expand All @@ -110,26 +143,7 @@ const SummaryEntry = ({
) : (
<MemberDBSubtitle metadata={metadata} dbInfo={dbInfo} />
)}
<section>
{
// doesn't work for some HAMAP as they have enpty <P> tag
(metadata.description || []).length ? (
<>
<h4>{headerText}</h4>
<Description
textBlocks={metadata.description}
literature={included as Array<[string, Reference]>}
accession={metadata.accession}
/>
</>
) : (
<DescriptionFromIntegrated
integrated={metadata.integrated}
setIntegratedCitations={setIntegratedCitations}
/>
)
}
</section>
<section>{selectDescriptionComponent()}</section>
</div>
<div className={css('vf-stack')}>
<SidePanel metadata={metadata} dbInfo={dbInfo} />
Expand Down
1 change: 1 addition & 0 deletions src/custom.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -299,6 +299,7 @@ interface EntryMetadata extends Metadata {
accession: string;
name: string;
};
llm_description: string | null;
is_removed?: boolean;
}

Expand Down