the commander is told the rule, not the API
three sentences where there were fourteen. everything an action produces goes in this directory under classification/, never into the path being watched, and getting it there is the commander's problem to solve with whatever ran the action. what came out was me teaching it the transcription API — read the task's inputs, here is the endpoint that lists them, pass a destination. that is one task's detail in a file every commander reads, and the commander can discover it. the rule is the part only this file can state. the task half stays and is real: transcribe-audio-file takes an optional output_dir now, marked `hidden` so the file browser neither renders it nor counts it as something to ask a person about. without that, declaring it would have turned the direct right-click run back into a modal with a field nobody clicking a file has an answer for. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Officer-Session: 656f5c85-e49a-4f1f-b9f3-042a04b4d043
This commit is contained in:
+3
-1
@@ -279,6 +279,8 @@ export type TaskInputDef = {
|
||||
default?: string;
|
||||
options?: string[];
|
||||
autofill?: string;
|
||||
/** For a caller with no browser — never rendered, never asked about. See `useTasks.ts`. */
|
||||
hidden?: boolean;
|
||||
};
|
||||
|
||||
type TaskInputFormProps = {
|
||||
@@ -332,7 +334,7 @@ export const TaskInputForm = ({
|
||||
hideTrackPickers,
|
||||
}: TaskInputFormProps) => {
|
||||
const { t } = useTranslation();
|
||||
const configurableInputs = Object.entries(inputDefs).filter(([key]) => !autoFilledKeys.has(key));
|
||||
const configurableInputs = Object.entries(inputDefs).filter(([key, def]) => !autoFilledKeys.has(key) && !def.hidden);
|
||||
if (configurableInputs.length === 0) return null;
|
||||
|
||||
return (
|
||||
|
||||
@@ -104,3 +104,14 @@ test('agentic and pipeline always take the modal', () => {
|
||||
expect(runsWithoutPrompting(scriptTask({ mode: 'agentic' }))).toBe(false);
|
||||
expect(runsWithoutPrompting(scriptTask({ mode: 'pipeline' }))).toBe(false);
|
||||
});
|
||||
|
||||
// An input that exists for a caller with no browser — a commander passing its own output directory.
|
||||
// Declaring one must not turn a direct right-click run back into a modal with a field nobody clicking a
|
||||
// file has an answer for.
|
||||
test('a hidden input is not something to ask a person about', () => {
|
||||
expect(
|
||||
runsWithoutPrompting(
|
||||
scriptTask({ inputs: { file_path: { required: true }, output_dir: { required: false, hidden: true } } }),
|
||||
),
|
||||
).toBe(true);
|
||||
});
|
||||
|
||||
@@ -11,6 +11,14 @@ export type TaskInputSpec = {
|
||||
autofill?: string;
|
||||
required?: boolean;
|
||||
options?: unknown;
|
||||
/**
|
||||
* Not for a person. An input that exists for callers with no browser — a commander passing its own
|
||||
* output directory — and that the file browser must neither show nor count as something to ask about.
|
||||
*
|
||||
* Without this, declaring one turns a direct right-click run back into a modal with a field nobody
|
||||
* clicking a file has an answer for.
|
||||
*/
|
||||
hidden?: boolean;
|
||||
};
|
||||
|
||||
export type TaskSummary = {
|
||||
@@ -55,7 +63,7 @@ export type TaskSummary = {
|
||||
const BROWSER_AUTOFILL = new Set(['entry_name', 'entry_path']);
|
||||
|
||||
const isFilledByBrowser = (key: string, spec: TaskInputSpec): boolean =>
|
||||
key === 'file_path' || (!!spec.autofill && BROWSER_AUTOFILL.has(spec.autofill));
|
||||
spec.hidden === true || key === 'file_path' || (!!spec.autofill && BROWSER_AUTOFILL.has(spec.autofill));
|
||||
|
||||
export const runsWithoutPrompting = (task: TaskSummary): boolean => {
|
||||
if (task.mode !== 'script') return false;
|
||||
|
||||
Reference in New Issue
Block a user