Add progress bar and update UI feedback for profile extraction process

This commit is contained in:
MartinBraquet
2026-04-07 22:19:25 +02:00
parent 8f9e339711
commit ed5aa80848
2 changed files with 24 additions and 16 deletions

View File

@@ -24,6 +24,7 @@ import {ProfileWithoutUser} from 'common/profiles/profile'
import {SITE_ORDER} from 'common/socials'
import {removeNullOrUndefinedProps} from 'common/util/object'
import {parseJsonContentToText} from 'common/util/parse'
import {HOUR_MS, MINUTE_MS} from 'common/util/time'
import {createHash} from 'crypto'
import {promises as fs} from 'fs'
import {tmpdir} from 'os'
@@ -34,8 +35,8 @@ import {convertToJSONContent, extractGoogleDocId} from 'shared/parse'
const MAX_CONTEXT_LENGTH = 7 * 10 * 30 * 50
const USE_CACHE = true
const CACHE_DIR = join(tmpdir(), 'compass-llm-cache')
const CACHE_TTL_MS = 24 * 60 * 60 * 1000 // 24 hours
const PROCESSING_TTL_MS = 10 * 60 * 1000 // 10 minutes
const CACHE_TTL_MS = 24 * HOUR_MS
const PROCESSING_TTL_MS = 10 * MINUTE_MS
interface ParsedBody {
content?: string
@@ -268,6 +269,11 @@ async function processAndCache(
url?: string | undefined,
locale?: string,
): Promise<void> {
log('Extracting profile from content', {
contentLength: content?.length,
url,
locale,
})
try {
let bio: JSONContent | undefined
if (!content) {
@@ -570,20 +576,10 @@ export async function fetchOnlineProfile(url: string | undefined): Promise<JSONC
}
}
export const llmExtractProfileEndpoint: APIHandler<'llm-extract-profile'> = async (
parsedBody,
auth,
) => {
export const llmExtractProfileEndpoint: APIHandler<'llm-extract-profile'> = async (parsedBody) => {
const {url, locale} = parsedBody
const content = parsedBody.content
log('Extracting profile from content', {
contentLength: content?.length,
url,
locale,
userId: auth.uid,
})
if (content && url) {
throw APIErrors.badRequest('Content and URL cannot be provided together')
}

View File

@@ -11,6 +11,7 @@ interface LLMExtractSectionProps {
isExtracting: boolean
isSubmitting: boolean
onExtract: () => void
progress: number
}
export function LLMExtractSection({
@@ -19,6 +20,7 @@ export function LLMExtractSection({
isExtracting,
isSubmitting,
onExtract,
progress,
}: LLMExtractSectionProps) {
const t = useT()
const parsingText = parsingEditor?.getText?.()
@@ -50,15 +52,25 @@ export function LLMExtractSection({
'Insert a URL or paste your profile content here.',
)}
/>
{isExtracting && (
<div className="w-full h-2 bg-canvas-200 rounded-full overflow-hidden">
<div
className="h-full bg-primary-500 transition-all duration-100 ease-linear rounded-full"
style={{width: `${Math.min(progress, 100)}%`}}
/>
</div>
)}
<Button
onClick={onExtract}
disabled={isExtracting || !parsingEditor?.getJSON?.() || isSubmitting}
loading={isExtracting}
className="self-start"
>
{isUrl(parsingText)
? t('profile.llm.extract.button_url', 'Extract Profile Data from URL')
: t('profile.llm.extract.button_text', 'Extract Profile Data from Text')}
{isExtracting
? t('profile.llm.extract.button_extracting', 'Extracting Profile Data')
: isUrl(parsingText)
? t('profile.llm.extract.button_url', 'Extract Profile Data from URL')
: t('profile.llm.extract.button_text', 'Extract Profile Data from Text')}
</Button>
</Col>
)