-
Notifications
You must be signed in to change notification settings - Fork 17
Feature: AI project keyword suggestions #1597
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
Open
van-go
wants to merge
26
commits into
main
Choose a base branch
from
task/WIN-40-keyword-suggestion-client-side-component
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
+4,487
−357
Open
Changes from 23 commits
Commits
Show all changes
26 commits
Select commit
Hold shift + click to select a range
e9296a1
add back NH Type, Year Pub, and Clear filters
van-go 795c38f
Merge branch 'main' of https://github.com/DesignSafe-CI/portal
van-go e010ff5
Client side component to render keyword suggestions
van-go f6f4918
formating
van-go 78d1156
remove unused imports
van-go bfe7729
chore: re-export useKeywordSuggestions in central @client/hooks barre…
van-go 200c88b
update mapping
van-go 66a3cc3
Merge branch 'main' into task/WIN-40-keyword-suggestion-client-side-c…
rstijerina 70633b1
Merge branch 'main' into task/WIN-40-keyword-suggestion-client-side-c…
rstijerina 4ae8e6e
Merge branch 'main' into task/WIN-40-keyword-suggestion-client-side-c…
rstijerina c833fb4
Merge branch 'main' into task/WIN-40-keyword-suggestion-client-side-c…
rstijerina b22b92b
task/WIN-41: Keyword RAG as view (#1616)
rstijerina d1a0361
Merge branch 'main' into task/WIN-40-keyword-suggestion-client-side-c…
rstijerina 78d0541
Merge branch 'main' into task/WIN-40-keyword-suggestion-client-side-c…
rstijerina ae32f4b
add auth to chromadb connection
rstijerina f65b89a
add comments; rename variable
rstijerina 2e7cc14
add CHROMA_COLLECTION setting
rstijerina 1051d97
add score threshold, increase returned documents to 10
rstijerina fe2997f
only render 10 suggestions at a time
rstijerina d3da95c
task/WIN-40: Add publication metadata to chromadb as part of publicat…
rstijerina c5ffe0d
Merge branch 'main' into task/WIN-40-keyword-suggestion-client-side-c…
rstijerina 12d4131
move keyword field below description. add helper text to keyword sugg…
van-go 39b87b4
Merge branch 'main' into task/WIN-40-keyword-suggestion-client-side-c…
rstijerina 7c2285d
New <KeywordSuggestor /> component
van-go d19bfb6
Merge branch 'task/WIN-40-keyword-suggestion-client-side-component' o…
van-go 8bb271b
fix linting
van-go File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or 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
33 changes: 33 additions & 0 deletions
33
client/modules/_hooks/src/datafiles/useKeywordSuggestions.ts
This file contains hidden or 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,33 @@ | ||
| import { useQuery } from '@tanstack/react-query'; | ||
| import apiClient from '../apiClient'; | ||
|
|
||
| export type TGetKeywordSuggestionsParams = { | ||
| title: string; | ||
| description: string; | ||
| }; | ||
|
|
||
| export interface KeywordSuggestionResponse { | ||
| response: string[]; | ||
| } | ||
|
|
||
| export function useKeywordSuggestions( | ||
| searchParams: TGetKeywordSuggestionsParams | ||
| ) { | ||
| return useQuery({ | ||
| queryKey: [ | ||
| 'keywordSuggestions', | ||
| , | ||
| searchParams.title.trim(), | ||
| searchParams.description.trim(), | ||
| ], | ||
| queryFn: async () => { | ||
| const res = await apiClient.get<KeywordSuggestionResponse>( | ||
| '/api/keyword-suggestions/', | ||
| { params: searchParams } | ||
| ); | ||
| return res.data.response; | ||
| }, | ||
| enabled: !!searchParams.title.trim() && !!searchParams.description.trim(), | ||
| staleTime: 0, | ||
| }); | ||
| } |
This file contains hidden or 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
95 changes: 95 additions & 0 deletions
95
client/modules/datafiles/src/projects/forms/KeywordSuggestor.tsx
This file contains hidden or 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,95 @@ | ||
| // KeywordSuggestor.tsx | ||
| import React, { useMemo } from 'react'; | ||
| import { Form, Tag, Spin } from 'antd'; | ||
| import type { FormInstance } from 'antd'; | ||
| import { useDebounceValue, useKeywordSuggestions } from '@client/hooks'; | ||
|
|
||
| type Props = { | ||
| form: FormInstance; | ||
| titlePath: (string | number)[]; | ||
| descriptionPath: (string | number)[]; | ||
| keywordsPath: (string | number)[]; | ||
| }; | ||
|
|
||
| export const KeywordSuggestor: React.FC<Props> = ({ | ||
| form, | ||
| titlePath, | ||
| descriptionPath, | ||
| keywordsPath, | ||
| }) => { | ||
| const title: string = Form.useWatch(titlePath, form) ?? ''; | ||
| const description: string = Form.useWatch(descriptionPath, form) ?? ''; | ||
| const keywords: string[] = Form.useWatch(keywordsPath, form) ?? []; | ||
|
|
||
| const debounced = useDebounceValue( | ||
| { title: title.trim(), description: description.trim() }, | ||
| 800 | ||
| ); | ||
|
|
||
| const { | ||
| data: suggestions = [], | ||
| isLoading, | ||
| isFetching, | ||
| error, | ||
| } = useKeywordSuggestions(debounced); | ||
|
|
||
| const available = useMemo( | ||
| () => suggestions.filter((kw) => !keywords.includes(kw)), | ||
| [suggestions, keywords] | ||
| ); | ||
|
|
||
| const hasText = | ||
| debounced.title.length > 0 && debounced.description.length > 0; | ||
|
|
||
| if (!hasText) { | ||
| return ( | ||
| <div style={{ marginTop: 8 }}> | ||
| <span>Suggested Keywords: </span> | ||
| <em style={{ color: 'rgba(0,0,0,.45)' }}> | ||
| Enter a project <strong>title</strong> and{' '} | ||
| <strong>description</strong> to see keyword suggestions. | ||
| </em> | ||
| </div> | ||
| ); | ||
| } | ||
|
|
||
| if (error) return null; | ||
fnets marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
|
||
| const list = available.slice(0, 10); | ||
| const loading = isLoading || isFetching; | ||
|
|
||
| return ( | ||
| <div style={{ marginTop: 8 }}> | ||
| <p style={{ marginBottom: 6 }}>Suggested Keywords:</p> | ||
|
|
||
| {/* While loading and nothing cached yet, show a friendly status instead of an empty area */} | ||
| {loading && list.length === 0 ? ( | ||
| <div | ||
| aria-live="polite" | ||
| style={{ display: 'inline-flex', gap: 8, alignItems: 'center' }} | ||
| > | ||
| <Spin size="small" /> | ||
| <em style={{ color: 'rgba(0,0,0,.45)' }}>Finding suggestions…</em> | ||
| </div> | ||
| ) : list.length === 0 ? ( | ||
| <em style={{ color: 'rgba(0,0,0,.45)' }}>No suggestions yet.</em> | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Another annoying can of worms that I might be opening up, but are there any CSS classes or styling we would want to use instead of setting it manually in the JSX like you do in this chunk? We haven't talked to Wes or anyone yet, so maybe that will be a to-do for later. |
||
| ) : ( | ||
| list.map((kw) => ( | ||
| <Tag | ||
| key={kw} | ||
| color="blue" | ||
| style={{ cursor: 'pointer', marginBottom: 4 }} | ||
| onClick={() => { | ||
| const current: string[] = form.getFieldValue(keywordsPath) || []; | ||
| if (!current.includes(kw)) { | ||
| form.setFieldValue(keywordsPath, [...current, kw]); | ||
| } | ||
| }} | ||
| > | ||
| {kw} | ||
| </Tag> | ||
| )) | ||
| )} | ||
| </div> | ||
| ); | ||
| }; | ||
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
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.
This is a great idea