Skip to content

Commit

Permalink
Merge branch 'dev' into staging
Browse files Browse the repository at this point in the history
  • Loading branch information
JoeSlain committed Jan 14, 2025
2 parents 414aa4b + 15953e3 commit 5901ce8
Show file tree
Hide file tree
Showing 4 changed files with 73 additions and 43 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ Nous utilisons [ViteJS](https://vitejs.dev/) pour construire le projet donc chaq
**VITE_ENVIRONMENT_NAME** -- une variable optionnelle utilisée pour afficher des fonctionnalités spécifiques pour les usagers de France Services.

**VITE_MODEL_NAME** -- le modèle à utiliser pour les requêtes, vous pouvez trouver une liste ici [ici](https://huggingface.co/AgentPublic)
**VITE_MODEL_MODE** -- chaque modèle possède plusieurs modes lui permettant de répondre différemment: rag, rag-gt
**VITE_MODEL_MODE** -- chaque modèle possède plusieurs modes lui permettant de répondre différemment: rag, rag-gt-operators-llama
**VITE_MODEL_TEMPERATURE** -- la température utilisée par le modèle pour générer la réponse. Entre 1 et 100

## API
Expand Down
47 changes: 6 additions & 41 deletions src/components/Meeting/MeetingStream.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,53 +5,18 @@ import { TextWithSources } from 'components/Sources/TextWithSources'
import { GlobalParagraph } from 'components/Global/GlobalParagraph'
import Separator from 'components/Global/Separator'
import { Feedback } from '../Feedbacks/Feedback'
import { useStreamText } from 'hooks/useStreamText'

export function MeetingStream() {
const stream = useSelector((state: RootState) => state.stream)
const agentResponse = stream.historyStream[0]

// For letter-by-letter text
const [displayedText, setDisplayedText] = useState('')
const lastIndexRef = useRef(0)

// We'll detect a new question/stream by checking user.lastStreamId
const user = useSelector((state: RootState) => state.user)
const [prevStreamId, setPrevStreamId] = useState<number | null>(null)

// 1) Reset on new question
useEffect(() => {
// If lastStreamId changed => a brand-new question is being asked
if (user.lastStreamId && user.lastStreamId !== prevStreamId) {
setDisplayedText('')
lastIndexRef.current = 0
setPrevStreamId(user.lastStreamId)
}
}, [user.lastStreamId, prevStreamId])

// 2) Append text while streaming
useEffect(() => {
if (!stream.isStreaming) return

const intervalId = setInterval(() => {
if (lastIndexRef.current < stream.response.length) {
setDisplayedText((prev) => {
const nextChar = stream.response[lastIndexRef.current]
lastIndexRef.current += 1
return prev + nextChar
})
}
}, 0) // speed as desired

return () => clearInterval(intervalId)
}, [stream.isStreaming, stream.response])

// 3) Once streaming is done, ensure full text is displayed
useEffect(() => {
if (!stream.isStreaming && stream.response) {
setDisplayedText(stream.response)
lastIndexRef.current = stream.response.length
}
}, [stream.isStreaming, stream.response])
const displayedText = useStreamText({
text: stream.response,
isStreaming: stream.isStreaming,
streamId: user.lastStreamId,
})

return (
<div>
Expand Down
55 changes: 55 additions & 0 deletions src/hooks/useStreamText.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
import { useState, useRef, useEffect } from 'react'

interface StreamTextOptions {
text: string
isStreaming: boolean
streamId?: number | null
speed?: number
}

export function useStreamText({
text,
isStreaming,
streamId = null,
speed = 0,
}: StreamTextOptions) {
const [displayedText, setDisplayedText] = useState('')
const lastIndexRef = useRef(0)
const [prevStreamId, setPrevStreamId] = useState<number | null>(null)

// Reset on new stream
useEffect(() => {
if (streamId && streamId !== prevStreamId) {
setDisplayedText('')
lastIndexRef.current = 0
setPrevStreamId(streamId)
}
}, [streamId, prevStreamId])

// Append text while streaming
useEffect(() => {
if (!isStreaming) return

const intervalId = setInterval(() => {
if (lastIndexRef.current < text.length) {
setDisplayedText((prev) => {
const nextChar = text[lastIndexRef.current]
lastIndexRef.current += 1
return prev + nextChar
})
}
}, speed)

return () => clearInterval(intervalId)
}, [isStreaming, text, speed])

// Ensure full text is displayed when streaming ends
useEffect(() => {
if (!isStreaming && text) {
setDisplayedText(text)
lastIndexRef.current = text.length
}
}, [isStreaming, text])

return displayedText
}
12 changes: 11 additions & 1 deletion src/pages/Evaluations.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ import { useLocation, useNavigate } from 'react-router-dom'
import { onCloseStream } from '../utils/eventsEmitter'
import { fr } from '@codegouvfr/react-dsfr'
//import ShowError from 'components/Error/ShowError'
import { useStreamText } from 'hooks/useStreamText'

const questions = [
{
Expand Down Expand Up @@ -591,8 +592,15 @@ function AnswerPannel({
}) {
const scrollRef = useRef(null)
const [response, setResponse] = useState('')
const [isStreaming, setIsStreaming] = useState(false)
const [isUserScrolledUp, setIsUserScrolledUp] = useState(false)

const displayedText = useStreamText({
text: response,
isStreaming,
speed: 0,
})

const prompt = {
chat_type: 'evaluations',
themes: [theme],
Expand Down Expand Up @@ -654,11 +662,13 @@ function AnswerPannel({
stream_chat.onmessage = (e) => {
const jsonData = JSON.parse(e.data)
setResponse((prev) => prev + jsonData.choices[0].delta.content)
setIsStreaming(true)

if (jsonData.choices[0].finish_reason === 'stop') {
stream_chat.close()
setIsUserScrolledUp(false)
setIsStreamFinished(true)
setIsStreaming(false)
}
}

Expand Down Expand Up @@ -713,7 +723,7 @@ function AnswerPannel({
className="shadow-inner fr-mt-1v rounded-lg fr-px-2w h-[50vh] overflow-y-scroll"
>
<p>
<TextWithSources text={response} />
<TextWithSources text={displayedText} />
</p>
</div>
</div>
Expand Down

0 comments on commit 5901ce8

Please sign in to comment.