mirror of
https://github.com/NousResearch/hermes-agent.git
synced 2026-07-31 19:16:29 +00:00
fix(desktop): queue prompts during context compaction (#69783)
This commit is contained in:
parent
5c4d358a7e
commit
dbf4f69b72
6 changed files with 147 additions and 18 deletions
|
|
@ -8,10 +8,11 @@ import { useComposerSubmit } from './use-composer-submit'
|
|||
interface SubmitHarnessOptions {
|
||||
attachments?: ComposerAttachment[]
|
||||
busy?: boolean
|
||||
compacting?: boolean
|
||||
text?: string
|
||||
}
|
||||
|
||||
function renderSubmitHook({ attachments = [], busy = false, text = '' }: SubmitHarnessOptions = {}) {
|
||||
function renderSubmitHook({ attachments = [], busy = false, compacting = false, text = '' }: SubmitHarnessOptions = {}) {
|
||||
const draftRef = { current: text }
|
||||
const editor = document.createElement('div')
|
||||
editor.dataset.slot = 'composer-rich-input'
|
||||
|
|
@ -33,6 +34,7 @@ function renderSubmitHook({ attachments = [], busy = false, text = '' }: SubmitH
|
|||
activeQueueSessionKeyRef: { current: 'stored-session' },
|
||||
attachments,
|
||||
busy,
|
||||
compacting,
|
||||
clearDraft,
|
||||
disabled: false,
|
||||
draftRef,
|
||||
|
|
@ -79,6 +81,23 @@ describe('useComposerSubmit busy-turn routing', () => {
|
|||
expect(onSubmit).not.toHaveBeenCalled()
|
||||
})
|
||||
|
||||
it('queues a plain-text follow-up while the active turn is compacting', () => {
|
||||
const { hook, onCancel, onSteer, onSubmit, queueCurrentDraft } = renderSubmitHook({
|
||||
busy: true,
|
||||
compacting: true,
|
||||
text: 'wait for the summary'
|
||||
})
|
||||
|
||||
act(() => {
|
||||
hook.result.current.submitDraft()
|
||||
})
|
||||
|
||||
expect(queueCurrentDraft).toHaveBeenCalledTimes(1)
|
||||
expect(onSteer).not.toHaveBeenCalled()
|
||||
expect(onSubmit).not.toHaveBeenCalled()
|
||||
expect(onCancel).not.toHaveBeenCalled()
|
||||
})
|
||||
|
||||
it('runs slash commands immediately while busy', async () => {
|
||||
const { clearDraft, hook, onCancel, onSteer, onSubmit, queueCurrentDraft } = renderSubmitHook({
|
||||
busy: true,
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@ interface UseComposerSubmitArgs {
|
|||
activeQueueSessionKeyRef: RefObject<string | null>
|
||||
attachments: ComposerAttachment[]
|
||||
busy: boolean
|
||||
compacting: boolean
|
||||
clearDraft: () => void
|
||||
disabled: boolean
|
||||
draftRef: RefObject<string>
|
||||
|
|
@ -51,6 +52,7 @@ export function useComposerSubmit({
|
|||
activeQueueSessionKeyRef,
|
||||
attachments,
|
||||
busy,
|
||||
compacting,
|
||||
clearDraft,
|
||||
disabled,
|
||||
draftRef,
|
||||
|
|
@ -149,7 +151,7 @@ export function useComposerSubmit({
|
|||
triggerHaptic('submit')
|
||||
clearDraft()
|
||||
dispatchSubmit(text)
|
||||
} else if (!attachments.length && text.trim()) {
|
||||
} else if (!compacting && !attachments.length && text.trim()) {
|
||||
// Cursor-style stop-and-correct: interrupt the live turn and redirect
|
||||
// it with this text. redirect() preserves the shown reasoning/work; if
|
||||
// the turn already ended, steerDraft re-queues so nothing is lost.
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@ import { sanitizeComposerInput } from '@/lib/composer-input-sanitize'
|
|||
import { DATA_IMAGE_URL_RE } from '@/lib/embedded-images'
|
||||
import { triggerHaptic } from '@/lib/haptics'
|
||||
import { cn } from '@/lib/utils'
|
||||
import { $compactionActive } from '@/store/compaction'
|
||||
import { browseBackward, browseForward, deriveUserHistory, isBrowsingHistory } from '@/store/composer-input-history'
|
||||
import { POPOUT_WIDTH_REM } from '@/store/composer-popout'
|
||||
import { parkQueuedPrompts, removeQueuedPrompt, unparkQueuedPrompts } from '@/store/composer-queue'
|
||||
|
|
@ -104,6 +105,7 @@ export function ChatBar({
|
|||
// focus-bus key, and awaiting-input edge. Main scope = the legacy globals.
|
||||
const scope = useComposerScope()
|
||||
const attachments = useStore(scope.attachments.$attachments)
|
||||
const compacting = useStore($compactionActive)
|
||||
const scrolledUp = useStore($threadScrolledUp)
|
||||
const autoSpeak = useStore($autoSpeakReplies)
|
||||
// The turn is parked on the user (clarify / approval / sudo / secret). Esc must
|
||||
|
|
@ -230,11 +232,15 @@ export function ChatBar({
|
|||
|
||||
// Steer only makes sense mid-turn, text-only (the gateway can't carry images
|
||||
// into a tool result) and never for a slash command (those execute inline).
|
||||
const canSteer = busy && !!onSteer && attachments.length === 0 && isSteerableText
|
||||
const canSteer = busy && !compacting && !!onSteer && attachments.length === 0 && isSteerableText
|
||||
|
||||
// While busy: text redirects the live turn (Cursor-style stop-and-correct),
|
||||
// attachments queue for the next turn, an empty composer stops.
|
||||
const busyAction: 'steer' | 'queue' | 'stop' = canSteer ? 'steer' : hasComposerPayload ? 'queue' : 'stop'
|
||||
const busyAction: 'steer' | 'queue' | 'stop' = canSteer
|
||||
? 'steer'
|
||||
: compacting || hasComposerPayload
|
||||
? 'queue'
|
||||
: 'stop'
|
||||
|
||||
// The submit engine — the orchestration seam where draft + queue meet. Owns
|
||||
// the submit decision tree, the send-with-restore primitive, and steer.
|
||||
|
|
@ -243,6 +249,7 @@ export function ChatBar({
|
|||
activeQueueSessionKeyRef,
|
||||
attachments,
|
||||
busy,
|
||||
compacting,
|
||||
clearDraft,
|
||||
disabled,
|
||||
draftRef,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue