Skip to content

Commit

Permalink
feat: ASAP-463 Generate short-description with AI (#4299)
Browse files Browse the repository at this point in the history
* implement the back-end
* add button and call the API
* add env vars to the CI and config
* align the count with the generate button
* disable the generate button for empty desc
  • Loading branch information
peterstarling authored Jun 14, 2024
1 parent ff8378e commit 5bdca75
Show file tree
Hide file tree
Showing 52 changed files with 892 additions and 70 deletions.
4 changes: 4 additions & 0 deletions .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -37,3 +37,7 @@ [email protected]
EMAIL_BCC=[email protected]
CI_COMMIT_SHA=local
AWS_XRAY_LOG_LEVEL=silent


# OpenAI
OPENAI_API_KEY=
4 changes: 4 additions & 0 deletions .github/actions/sls-deployment/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,9 @@ inputs:
hostname:
description: 'Hostname'
required: true
openai-api-key:
description: 'OpenAI API Key'
required: false
sentry-dsn-api:
description: 'Sentry DSN for the API'
required: true
Expand Down Expand Up @@ -124,6 +127,7 @@ runs:
HOSTNAME: ${{ inputs.hostname }}
NODE_ENV: 'production'
NODE_OPTIONS: '--max-old-space-size=8192'
OPENAI_API_KEY: ${{ inputs.openai-api-key }}
SENTRY_DSN_API: ${{ inputs.sentry-dsn-api }}
SENTRY_DSN_PUBLIC_API: ${{ inputs.sentry-dsn-public-api }}
SENTRY_DSN_HANDLERS: ${{ inputs.sentry-dsn-handlers }}
Expand Down
4 changes: 4 additions & 0 deletions .github/actions/sls-package/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,9 @@ inputs:
hostname:
description: 'Hostname'
required: true
openai-api-key:
description: 'OpenAI API Key'
required: false
sentry-dsn-api:
description: 'Sentry DSN for the API'
required: true
Expand Down Expand Up @@ -125,6 +128,7 @@ runs:
HOSTNAME: ${{ inputs.hostname }}
NODE_ENV: 'production'
NODE_OPTIONS: '--max-old-space-size=8192'
OPENAI_API_KEY: ${{ inputs.openai-api-key }}
SENTRY_DSN_API: ${{ inputs.sentry-dsn-api }}
SENTRY_DSN_PUBLIC_API: ${{ inputs.sentry-dsn-public-api }}
SENTRY_DSN_HANDLERS: ${{ inputs.sentry-dsn-handlers }}
Expand Down
1 change: 1 addition & 0 deletions .github/actions/sls-remove/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,7 @@ runs:
HOSTNAME: ${{ inputs.hostname }}
NODE_ENV: 'production'
NODE_OPTIONS: '--max-old-space-size=8192'
OPENAI_API_KEY: 'n-a'
SENTRY_DSN_API: ${{ inputs.sentry-dsn-api }}
SENTRY_DSN_PUBLIC_API: ${{ inputs.sentry-dsn-public-api }}
SENTRY_DSN_HANDLERS: ${{ inputs.sentry-dsn-handlers }}
Expand Down
2 changes: 2 additions & 0 deletions .github/workflows/on-push-branch.yml
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@ jobs:
GP2_CONTENTFUL_ACCESS_TOKEN: ${{ secrets.GP2_CONTENTFUL_ACCESS_TOKEN }}
GP2_CONTENTFUL_PREVIEW_ACCESS_TOKEN: ${{ secrets.GP2_CONTENTFUL_PREVIEW_ACCESS_TOKEN }}
GP2_CONTENTFUL_WEBHOOK_AUTHENTICATION_TOKEN: ${{ secrets.GP2_CONTENTFUL_WEBHOOK_AUTHENTICATION_TOKEN }}
GP2_OPENAI_API_KEY: ${{ secrets.GP2_OPENAI_API_KEY }}
SLACK_WEBHOOK: 'n-a'

build-analysis:
Expand Down Expand Up @@ -126,6 +127,7 @@ jobs:
GP2_CONTENTFUL_ACCESS_TOKEN: ${{ secrets.GP2_CONTENTFUL_ACCESS_TOKEN }}
GP2_CONTENTFUL_PREVIEW_ACCESS_TOKEN: ${{ secrets.GP2_CONTENTFUL_PREVIEW_ACCESS_TOKEN }}
GP2_CONTENTFUL_WEBHOOK_AUTHENTICATION_TOKEN: ${{ secrets.GP2_CONTENTFUL_WEBHOOK_AUTHENTICATION_TOKEN }}
GP2_OPENAI_API_KEY: ${{ secrets.GP2_OPENAI_API_KEY }}
SLACK_WEBHOOK: 'n-a'

verify:
Expand Down
4 changes: 4 additions & 0 deletions .github/workflows/on-push-master.yml
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ jobs:
GP2_CONTENTFUL_ACCESS_TOKEN: ${{ secrets.GP2_CONTENTFUL_ACCESS_TOKEN }}
GP2_CONTENTFUL_PREVIEW_ACCESS_TOKEN: ${{ secrets.GP2_CONTENTFUL_PREVIEW_ACCESS_TOKEN }}
GP2_CONTENTFUL_WEBHOOK_AUTHENTICATION_TOKEN: ${{ secrets.GP2_CONTENTFUL_WEBHOOK_AUTHENTICATION_TOKEN }}
GP2_OPENAI_API_KEY: ${{ secrets.GP2_OPENAI_API_KEY }}
SLACK_WEBHOOK: 'n-a'

build-analysis-development:
Expand Down Expand Up @@ -68,6 +69,7 @@ jobs:
GP2_CONTENTFUL_ACCESS_TOKEN: ${{ secrets.GP2_CONTENTFUL_ACCESS_TOKEN }}
GP2_CONTENTFUL_PREVIEW_ACCESS_TOKEN: ${{ secrets.GP2_CONTENTFUL_PREVIEW_ACCESS_TOKEN }}
GP2_CONTENTFUL_WEBHOOK_AUTHENTICATION_TOKEN: ${{ secrets.GP2_CONTENTFUL_WEBHOOK_AUTHENTICATION_TOKEN }}
GP2_OPENAI_API_KEY: ${{ secrets.GP2_OPENAI_API_KEY }}
SLACK_WEBHOOK: ${{ secrets.SLACK_WEBHOOK }}

build-analysis-production:
Expand Down Expand Up @@ -100,6 +102,7 @@ jobs:
GP2_CONTENTFUL_ACCESS_TOKEN: ${{ secrets.GP2_CONTENTFUL_ACCESS_TOKEN }}
GP2_CONTENTFUL_PREVIEW_ACCESS_TOKEN: ${{ secrets.GP2_CONTENTFUL_PREVIEW_ACCESS_TOKEN }}
GP2_CONTENTFUL_WEBHOOK_AUTHENTICATION_TOKEN: ${{ secrets.GP2_CONTENTFUL_WEBHOOK_AUTHENTICATION_TOKEN }}
GP2_OPENAI_API_KEY: ${{ secrets.GP2_OPENAI_API_KEY }}
SLACK_WEBHOOK: 'n-a'

crn-contentful-migrate-empty:
Expand Down Expand Up @@ -187,6 +190,7 @@ jobs:
GP2_CONTENTFUL_ACCESS_TOKEN: ${{ secrets.GP2_CONTENTFUL_ACCESS_TOKEN }}
GP2_CONTENTFUL_PREVIEW_ACCESS_TOKEN: ${{ secrets.GP2_CONTENTFUL_PREVIEW_ACCESS_TOKEN }}
GP2_CONTENTFUL_WEBHOOK_AUTHENTICATION_TOKEN: ${{ secrets.GP2_CONTENTFUL_WEBHOOK_AUTHENTICATION_TOKEN }}
GP2_OPENAI_API_KEY: ${{ secrets.GP2_OPENAI_API_KEY }}
SLACK_WEBHOOK: ${{ secrets.SLACK_WEBHOOK }}

algolia-sync-production-crn:
Expand Down
4 changes: 4 additions & 0 deletions .github/workflows/reusable-build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,9 @@ on:
GP2_AUTH0_SHARED_SECRET:
description: 'GP2 Auth0 Shared Secret'
required: false
GP2_OPENAI_API_KEY:
description: 'GP2 OpenAI API Key'
required: true
SLACK_WEBHOOK:
description: 'Slack webhook URL'
required: false
Expand Down Expand Up @@ -367,6 +370,7 @@ jobs:
contentful-webhook-authentication-token: ${{ secrets.GP2_CONTENTFUL_WEBHOOK_AUTHENTICATION_TOKEN }}
environment-name: ${{ inputs.environment-name }}
hostname: ${{ steps.setup.outputs.gp2-hostname }}
openai-api-key: ${{ secrets.GP2_OPENAI_API_KEY }}
sentry-dsn-api: ${{ steps.setup.outputs.gp2-sentry-dsn-api }}
sentry-dsn-public-api: ${{ steps.setup.outputs.gp2-sentry-dsn-public-api }}
sentry-dsn-handlers: ${{ steps.setup.outputs.gp2-sentry-dsn-handlers }}
Expand Down
4 changes: 4 additions & 0 deletions .github/workflows/reusable-deployment.yml
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,9 @@ on:
required: false
GP2_CI_PR_AUTH0_CLIENT_SECRET:
description: 'GP2 CI PR Auth0 Client Secret'
GP2_OPENAI_API_KEY:
description: 'GP2 OpenAI API Key'
required: true
CONTENTFUL_MANAGEMENT_TOKEN:
description: 'Contentful Management Token'
required: true
Expand Down Expand Up @@ -163,6 +166,7 @@ jobs:
contentful-webhook-authentication-token: ${{ secrets.GP2_CONTENTFUL_WEBHOOK_AUTHENTICATION_TOKEN }}
environment-name: ${{ inputs.environment-name }}
hostname: ${{ steps.setup.outputs.gp2-hostname }}
openai-api-key: ${{ secrets.GP2_OPENAI_API_KEY }}
sentry-dsn-api: ${{ steps.setup.outputs.gp2-sentry-dsn-api }}
sentry-dsn-public-api: ${{ steps.setup.outputs.gp2-sentry-dsn-public-api }}
sentry-dsn-handlers: ${{ steps.setup.outputs.gp2-sentry-dsn-handlers }}
Expand Down
89 changes: 89 additions & 0 deletions .pnp.cjs

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
13 changes: 12 additions & 1 deletion apps/gp2-frontend/src/outputs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,11 @@ import {
isValidationErrorResponse,
ValidationErrorResponse,
} from '@asap-hub/model';
import { useRecoilValue } from 'recoil';
import { authorizationState } from './auth/state';
import { getEvents } from './events/api';
import { useAlgolia } from './hooks/algolia';
import { getOutputs } from './outputs/api';
import { getGeneratedOutputContent, getOutputs } from './outputs/api';
import { getUsersAndExternalUsers } from './users/api';

export const useRelatedOutputSuggestions = (currentId?: string) => {
Expand Down Expand Up @@ -71,6 +73,15 @@ export const useAuthorSuggestions = () => {
);
};

export const useOutputGeneratedContent = () => {
const authorization = useRecoilValue(authorizationState);

return (description: string): Promise<string> =>
getGeneratedOutputContent({ description }, authorization).then(
(output) => output.shortDescription || '',
);
};

export const handleError =
(
supportedErrors: string[],
Expand Down
3 changes: 3 additions & 0 deletions apps/gp2-frontend/src/outputs/ShareOutput.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import {
useRelatedOutputSuggestions,
useRelatedEventsSuggestions,
useAuthorSuggestions,
useOutputGeneratedContent,
} from '../outputs';
import { useProjects } from '../projects/state';
import { useContributingCohorts, useTags } from '../shared/state';
Expand All @@ -28,6 +29,7 @@ const ShareOutput: React.FC<ShareOutputProps> = ({
const getAuthorSuggestions = useAuthorSuggestions();
const getRelatedOutputSuggestions = useRelatedOutputSuggestions(output.id);
const getRelatedEventSuggestions = useRelatedEventsSuggestions();
const getShortDescriptionFromDescription = useOutputGeneratedContent();
const { items: tagSuggestions } = useTags();
const cohortSuggestions = useContributingCohorts();
const { items: workingGroupSuggestions } = useWorkingGroupsState();
Expand Down Expand Up @@ -61,6 +63,7 @@ const ShareOutput: React.FC<ShareOutputProps> = ({
)
}
getAuthorSuggestions={getAuthorSuggestions}
getShortDescriptionFromDescription={getShortDescriptionFromDescription}
tagSuggestions={tagSuggestions}
getRelatedOutputSuggestions={getRelatedOutputSuggestions}
getRelatedEventSuggestions={getRelatedEventSuggestions}
Expand Down
6 changes: 6 additions & 0 deletions apps/gp2-frontend/src/outputs/__mocks__/api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,3 +33,9 @@ export const updateOutput = jest.fn(
documentType,
}),
);

export const getGeneratedOutputContent = jest.fn(
async (): Promise<gp2Model.OutputGenerateContentResponse> => ({
shortDescription: 'summarised short description',
}),
);
Loading

0 comments on commit 5bdca75

Please sign in to comment.