feat: lots of speech stuff
This commit is contained in:
@@ -1,6 +1,5 @@
|
||||
import type { QueryClient } from '@tanstack/react-query'
|
||||
import { type MutableRefObject, useCallback } from 'react'
|
||||
import { flushSync } from 'react-dom'
|
||||
|
||||
import {
|
||||
appendReasoningPart,
|
||||
@@ -60,7 +59,6 @@ export function useMessageStream({
|
||||
transform: (parts: ChatMessagePart[], message: ChatMessage) => ChatMessagePart[],
|
||||
seed: () => ChatMessagePart[],
|
||||
opts: {
|
||||
sync?: boolean
|
||||
pending?: (message: ChatMessage) => boolean
|
||||
} = {}
|
||||
) => {
|
||||
@@ -112,7 +110,7 @@ export function useMessageStream({
|
||||
})
|
||||
}
|
||||
|
||||
opts.sync ? flushSync(apply) : apply()
|
||||
apply()
|
||||
},
|
||||
[updateSessionState]
|
||||
)
|
||||
@@ -126,8 +124,7 @@ export function useMessageStream({
|
||||
mutateStream(
|
||||
sessionId,
|
||||
parts => appendTextPart(parts, delta),
|
||||
() => [textPart(delta)],
|
||||
{ sync: true }
|
||||
() => [textPart(delta)]
|
||||
)
|
||||
},
|
||||
[mutateStream]
|
||||
@@ -152,8 +149,7 @@ export function useMessageStream({
|
||||
|
||||
return appendReasoningPart(parts, delta)
|
||||
},
|
||||
() => [reasoningPart(delta)],
|
||||
{ sync: true }
|
||||
() => [reasoningPart(delta)]
|
||||
)
|
||||
},
|
||||
[mutateStream]
|
||||
@@ -299,6 +295,7 @@ export function useMessageStream({
|
||||
const apply = explicitSid ? isActiveEvent : !activeSessionIdRef.current
|
||||
const modelChanged = typeof payload?.model === 'string'
|
||||
const providerChanged = typeof payload?.provider === 'string'
|
||||
const runningChanged = typeof payload?.running === 'boolean'
|
||||
|
||||
if (apply) {
|
||||
if (modelChanged) {
|
||||
@@ -320,6 +317,35 @@ export function useMessageStream({
|
||||
if (typeof payload?.personality === 'string') {
|
||||
setCurrentPersonality(normalizePersonalityValue(payload.personality))
|
||||
}
|
||||
|
||||
if (runningChanged && sessionId) {
|
||||
updateSessionState(sessionId, state => {
|
||||
const busy = Boolean(payload!.running)
|
||||
|
||||
if (state.busy === busy && (busy || !state.awaitingResponse)) {
|
||||
return state
|
||||
}
|
||||
|
||||
if (busy) {
|
||||
return {
|
||||
...state,
|
||||
busy
|
||||
}
|
||||
}
|
||||
|
||||
if (state.awaitingResponse && !state.sawAssistantPayload) {
|
||||
return state
|
||||
}
|
||||
|
||||
return {
|
||||
...state,
|
||||
awaitingResponse: false,
|
||||
busy,
|
||||
pendingBranchGroup: null,
|
||||
streamId: null
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
void refreshHermesConfig()
|
||||
@@ -355,11 +381,11 @@ export function useMessageStream({
|
||||
}
|
||||
} else if (event.type === 'reasoning.delta') {
|
||||
if (sessionId) {
|
||||
appendReasoningDelta(sessionId, coerceGatewayText(payload?.text))
|
||||
appendReasoningDelta(sessionId, coerceThinkingText(payload?.text))
|
||||
}
|
||||
} else if (event.type === 'reasoning.available') {
|
||||
if (sessionId) {
|
||||
appendReasoningDelta(sessionId, coerceGatewayText(payload?.text), true)
|
||||
appendReasoningDelta(sessionId, coerceThinkingText(payload?.text), true)
|
||||
}
|
||||
} else if (event.type === 'message.complete') {
|
||||
if (!sessionId) {
|
||||
|
||||
@@ -13,7 +13,7 @@ import {
|
||||
import { triggerHaptic } from '@/lib/haptics'
|
||||
import { $composerAttachments, clearComposerAttachments } from '@/store/composer'
|
||||
import { clearNotifications, notify, notifyError } from '@/store/notifications'
|
||||
import { $busy, $messages, setAwaitingResponse, setBusy } from '@/store/session'
|
||||
import { $busy, $messages, setAwaitingResponse, setBusy, setMessages } from '@/store/session'
|
||||
|
||||
import type { ClientSessionState, SlashExecResponse } from '../../types'
|
||||
|
||||
@@ -296,12 +296,34 @@ export function usePromptActions({
|
||||
)
|
||||
|
||||
const cancelRun = useCallback(async () => {
|
||||
if (!activeSessionId) {
|
||||
const sessionId = activeSessionId || activeSessionIdRef.current
|
||||
|
||||
busyRef.current = false
|
||||
setBusy(false)
|
||||
setAwaitingResponse(false)
|
||||
|
||||
const finalizeMessages = (messages: ChatMessage[]) =>
|
||||
messages.map(message =>
|
||||
message.pending
|
||||
? {
|
||||
...message,
|
||||
parts: chatMessageText(message).trim()
|
||||
? appendTextPart(message.parts, INTERRUPTED_MARKER)
|
||||
: [...message.parts, textPart(INTERRUPTED_MARKER.trim())],
|
||||
pending: false
|
||||
}
|
||||
: message
|
||||
)
|
||||
|
||||
if (!sessionId) {
|
||||
setMessages(finalizeMessages($messages.get()))
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
updateSessionState(activeSessionId, state => {
|
||||
updateSessionState(sessionId, state => {
|
||||
const streamId = state.streamId
|
||||
|
||||
const messages = streamId
|
||||
? state.messages.map(message =>
|
||||
message.id === streamId
|
||||
@@ -314,7 +336,7 @@ export function usePromptActions({
|
||||
}
|
||||
: message
|
||||
)
|
||||
: state.messages
|
||||
: finalizeMessages(state.messages)
|
||||
|
||||
return {
|
||||
...state,
|
||||
@@ -328,11 +350,11 @@ export function usePromptActions({
|
||||
})
|
||||
|
||||
try {
|
||||
await requestGateway('session.interrupt', { session_id: activeSessionId })
|
||||
await requestGateway('session.interrupt', { session_id: sessionId })
|
||||
} catch (err) {
|
||||
notifyError(err, 'Stop failed')
|
||||
}
|
||||
}, [activeSessionId, requestGateway, updateSessionState])
|
||||
}, [activeSessionId, activeSessionIdRef, busyRef, requestGateway, updateSessionState])
|
||||
|
||||
const reloadFromMessage = useCallback(
|
||||
async (parentId: string | null) => {
|
||||
|
||||
@@ -87,6 +87,11 @@ export function useSessionActions({
|
||||
|
||||
const createBackendSessionForSend = useCallback(async (): Promise<string | null> => {
|
||||
const created = await requestGateway<SessionCreateResponse>('session.create', { cols: 96 })
|
||||
|
||||
if (created.stored_session_id) {
|
||||
navigate(sessionRoute(created.stored_session_id), { replace: true })
|
||||
}
|
||||
|
||||
setActiveSessionId(created.session_id)
|
||||
activeSessionIdRef.current = created.session_id
|
||||
ensureSessionState(created.session_id, created.stored_session_id ?? null)
|
||||
@@ -94,7 +99,6 @@ export function useSessionActions({
|
||||
if (created.stored_session_id) {
|
||||
setSelectedStoredSessionId(created.stored_session_id)
|
||||
selectedStoredSessionIdRef.current = created.stored_session_id
|
||||
navigate(sessionRoute(created.stored_session_id), { replace: true })
|
||||
}
|
||||
|
||||
if (created.info?.model) {
|
||||
|
||||
Reference in New Issue
Block a user