diff --git a/src/workspaces/officerdev/src/apps/Chat/background-job-prompt.ts b/src/workspaces/officerdev/src/apps/Chat/background-job-prompt.ts index 59182667..e511f058 100644 --- a/src/workspaces/officerdev/src/apps/Chat/background-job-prompt.ts +++ b/src/workspaces/officerdev/src/apps/Chat/background-job-prompt.ts @@ -18,17 +18,22 @@ export type BackgroundJobSpec = { condition: string; /** Whether firing ends the job. Ignored without a condition. */ stopOnFire: boolean; - /** `session` = until this chat ends. A number = minutes. `until-stopped` = until told otherwise. */ - duration: 'session' | 'until-stopped' | number; + /** + * Minutes to run for, or `null` to run until stopped. + * + * There used to be a "this session" option. It meant nothing: the backend deliberately holds the agent + * process alive while a job is running, so closing the browser does not end one — "this session" and + * "until stopped" were the same thing wearing two labels. + */ + duration: number | null; /** Where it runs. The panel's own directory, so nothing has to be typed. */ cwd: string; }; -const durationLine = (d: BackgroundJobSpec['duration']): string => { - if (d === 'session') return 'Run until this session ends. Do not bound the loop by time.'; - if (d === 'until-stopped') return 'Run until I stop it. Do not bound the loop by time.'; - return `Run for about ${d} minute${d === 1 ? '' : 's'}, then exit 1 to say it timed out.`; -}; +const durationLine = (d: BackgroundJobSpec['duration']): string => + d === null + ? 'Run until I stop it. Do not bound the loop by time.' + : `Run for about ${d} minute${d === 1 ? '' : 's'}, then exit 1 to say it timed out.`; export function buildBackgroundJobPrompt(spec: BackgroundJobSpec): string { const watching = spec.condition.trim().length > 0; diff --git a/src/workspaces/officerdev/src/apps/Chat/components/BackgroundJobDialog.tsx b/src/workspaces/officerdev/src/apps/Chat/components/BackgroundJobDialog.tsx index ff8a948b..cb4a79b9 100644 --- a/src/workspaces/officerdev/src/apps/Chat/components/BackgroundJobDialog.tsx +++ b/src/workspaces/officerdev/src/apps/Chat/components/BackgroundJobDialog.tsx @@ -34,15 +34,15 @@ type BackgroundJobDialogProps = { onSubmit: (intent: string, preamble: string) => void; }; -type Duration = 'session' | 'until-stopped' | 'timed'; - export const BackgroundJobDialog = ({ open, onOpenChange, cwd, onSubmit }: BackgroundJobDialogProps) => { const [mode, setMode] = useState<'command' | 'prompt'>('command'); const [body, setBody] = useState(''); const [watching, setWatching] = useState(false); const [condition, setCondition] = useState(''); const [stopOnFire, setStopOnFire] = useState(true); - const [duration, setDuration] = useState('session'); + // Unchecked means no time bound — the job runs until stopped. There is no third option: the backend + // keeps the agent alive while a job runs, so "this session" would have meant the same thing. + const [timed, setTimed] = useState(false); const [minutes, setMinutes] = useState(60); useEffect(() => { @@ -52,7 +52,7 @@ export const BackgroundJobDialog = ({ open, onOpenChange, cwd, onSubmit }: Backg setWatching(false); setCondition(''); setStopOnFire(true); - setDuration('session'); + setTimed(false); setMinutes(60); }, [open]); @@ -74,7 +74,7 @@ export const BackgroundJobDialog = ({ open, onOpenChange, cwd, onSubmit }: Backg body, condition: watching ? condition : '', stopOnFire, - duration: duration === 'timed' ? minutes : duration, + duration: timed ? minutes : null, cwd, }; // The intent is what the transcript shows; the preamble rides underneath it. @@ -151,36 +151,21 @@ export const BackgroundJobDialog = ({ open, onOpenChange, cwd, onSubmit }: Backg
- - - - {/* Said plainly rather than promised. The job is a descendant of this session's process, so - nothing here outlives the session — including "until stopped". */}

- All of these end if the session does — the job runs underneath it. + {timed ? 'Exits when the time is up, whether or not it fired.' : 'Runs until you stop it.'}