Preserve the quiet-worker wait through Off and tidy its settings row

Keep the previous accepted wait as the in-session draft, give the help text more space, and explain invalid input without the numeric safety limit.

Co-authored-by: Taras Kornichuk <dread9ko@gmail.com>
This commit is contained in:
Brennan Benson
2026-11-13 20:37:37 -08:00
co-authored by Taras Kornichuk
parent bdf701c81f
commit e4aff599dc
4 changed files with 49 additions and 42 deletions
@@ -35,6 +35,12 @@ it('records inherited Off as a choice and resets only on the explicit default ac
fireEvent.keyDown(input, { key: 'Enter' })
expect(settings.orchestrationQuietWorkerMinutes).toBe(23)
expect(document.activeElement).toBe(input)
fireEvent.change(input, { target: { value: 'invalid' } })
fireEvent.blur(input)
fireEvent.click(screen.getByRole('radio', { name: 'Off' }))
expect(settings.orchestrationQuietWorkerMinutes).toBe(0)
fireEvent.click(screen.getByRole('radio', { name: 'After' }))
expect(settings.orchestrationQuietWorkerMinutes).toBe(23)
write.mockClear()
for (const value of ['', '1.5', '-1', '0', '18764998448', '1e3']) {
fireEvent.change(screen.getByRole('textbox', { name: 'Minutes' }), { target: { value } })
@@ -2,10 +2,9 @@ import { useId, useState } from 'react'
import type { GlobalSettings } from '../../../../../shared/global-settings-types'
import {
isWorkerQuietMinutes,
MAX_WORKER_QUIET_MINUTES,
resolveWorkerQuietMinutes
} from '../../../../../shared/orchestration/workers/worker-quiet-settings'
import { useIntlLocale, useTranslate } from '@/i18n/use-translate'
import { useTranslate } from '@/i18n/use-translate'
import { Input } from '../../ui/input'
import { Button } from '../../ui/button'
import { SettingsRow, SettingsSegmentedControl } from '../form-controls/SettingsFormControls'
@@ -21,7 +20,6 @@ export function OrchestrationWorkerQuietSetting({
updateSettings
}: Props): React.JSX.Element {
const t = useTranslate()
const intlLocale = useIntlLocale()
const id = useId()
const raw = settings.orchestrationQuietWorkerMinutes
const minutes = resolveWorkerQuietMinutes(settings)
@@ -29,7 +27,8 @@ export function OrchestrationWorkerQuietSetting({
const [draft, setDraft] = useState({ raw, value: String(minutes || 15) })
const [invalid, setInvalid] = useState(false)
if (!Object.is(draft.raw, raw)) {
setDraft({ raw, value: minutes > 0 ? String(minutes) : draft.value })
const draftMinutes = minutes || (isWorkerQuietMinutes(draft.raw) ? draft.raw : 0)
setDraft({ raw, value: draftMinutes > 0 ? String(draftMinutes) : draft.value })
setInvalid(false)
}
const save = (value: number | null): void => {
@@ -49,6 +48,7 @@ export function OrchestrationWorkerQuietSetting({
}
return (
<SettingsRow
alignTop
labelId={id}
label={getWorkerQuietTitle(t)}
description={
@@ -73,15 +73,14 @@ export function OrchestrationWorkerQuietSetting({
<span id={`${id}-error`} role="alert" className="block text-destructive">
{t(
'auto.components.settings.OrchestrationPane.workerQuietInvalid',
'Enter a whole number of minutes between 1 and {{max}}.',
{ max: MAX_WORKER_QUIET_MINUTES.toLocaleString(intlLocale) }
'Enter a whole number of minutes (1 or more).'
)}
</span>
) : null}
</>
}
control={
<div className="flex flex-wrap items-center justify-end gap-2">
<div className="flex flex-col items-end gap-2">
<SettingsSegmentedControl
value={minutes ? 'after' : 'off'}
ariaLabelledBy={id}
@@ -97,38 +96,40 @@ export function OrchestrationWorkerQuietSetting({
]}
onChange={(value) => (value === 'off' ? save(0) : commit())}
/>
<Input
type="text"
inputMode="numeric"
aria-label={t(
'auto.components.settings.OrchestrationPane.workerQuietMinutes',
'Minutes'
)}
aria-invalid={invalid}
aria-describedby={invalid ? `${id}-error` : undefined}
value={draft.value}
onChange={(event) => {
setDraft({ raw, value: event.target.value })
setInvalid(false)
}}
onBlur={() => {
if (minutes > 0) {
commit()
}
}}
onKeyDown={(event) => {
if (event.key === 'Enter' && minutes > 0) {
commit()
}
}}
className="w-24"
/>
<span className="text-settings-detail text-muted-foreground">
{t('auto.components.settings.OrchestrationPane.workerQuietUnit', 'minutes')}
</span>
<Button variant="ghost" size="sm" disabled={!chosen} onClick={() => save(null)}>
{t('auto.components.settings.OrchestrationPane.workerQuietReset', 'Use default')}
</Button>
<div className="flex items-center gap-2">
<Input
type="text"
inputMode="numeric"
aria-label={t(
'auto.components.settings.OrchestrationPane.workerQuietMinutes',
'Minutes'
)}
aria-invalid={invalid}
aria-describedby={invalid ? `${id}-error` : undefined}
value={draft.value}
onChange={(event) => {
setDraft({ raw, value: event.target.value })
setInvalid(false)
}}
onBlur={() => {
if (minutes > 0) {
commit()
}
}}
onKeyDown={(event) => {
if (event.key === 'Enter' && minutes > 0) {
commit()
}
}}
className="w-24"
/>
<span className="text-settings-detail text-muted-foreground">
{t('auto.components.settings.OrchestrationPane.workerQuietUnit', 'minutes')}
</span>
<Button variant="ghost" size="sm" disabled={!chosen} onClick={() => save(null)}>
{t('auto.components.settings.OrchestrationPane.workerQuietReset', 'Use default')}
</Button>
</div>
</div>
}
/>
@@ -11,6 +11,6 @@ export function getWorkerQuietTitle(t: Translate = translate): string {
export function getWorkerQuietDescription(t: Translate = translate): string {
return t(
'auto.components.settings.OrchestrationPane.workerQuietDescription',
'This is only a notice. Workers keep running. Orca waits four times longer while a tool is running or progress is unavailable. Controls quiet notices generated by this Orca runtime. Other execution hosts use their own setting.'
'Notice only. Workers keep running. Waits 4× longer for tools or unavailable progress. Each host uses its own setting.'
)
}
+2 -2
View File
@@ -9183,7 +9183,7 @@
"nestedWorkerDepthTitle": "Nested worker depth",
"nestedWorkerDepthDescription": "How many generations of dispatched workers may spawn their own workers. 1 keeps the agent tree flat: a coordinator dispatches workers, and those workers do not dispatch.",
"workerQuietTitle": "Tell the coordinator when a worker has made no progress for…",
"workerQuietDescription": "This is only a notice. Workers keep running. Orca waits four times longer while a tool is running or progress is unavailable. Controls quiet notices generated by this Orca runtime. Other execution hosts use their own setting.",
"workerQuietDescription": "Notice only. Workers keep running. Waits 4× longer for tools or unavailable progress. Each host uses its own setting.",
"workerQuietChosen": "Your choice",
"workerQuietDefault": "Using default ({{value}})",
"workerQuietWait": "{{count}} minutes",
@@ -9192,7 +9192,7 @@
"workerQuietMinutes": "Minutes",
"workerQuietUnit": "minutes",
"workerQuietReset": "Use default",
"workerQuietInvalid": "Enter a whole number of minutes between 1 and {{max}}.",
"workerQuietInvalid": "Enter a whole number of minutes (1 or more).",
"workerAutoReleaseTitle": "Auto-close finished workers",
"workerAutoReleaseDescription": "Closes a worker's terminal or chat 2 minutes after it finishes, unless you choose Keep open. If it starts working again, the 2 minutes start over when it finishes.",
"workerAutoReleaseKeywordClose": "close",