Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .mux/workflows/.scratch/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
*
!.gitignore
4 changes: 2 additions & 2 deletions docs/hooks/tools.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -636,8 +636,8 @@ If a value is too large for the environment, it may be omitted (not set). Mux al
| `MUX_TOOL_INPUT_FILTER` | `filter` | string | Optional regex to filter bash task output lines. By default, only matching lines are returned. When filter_exclude is true, matching lines are excluded instead. Non-matching lines are discarded and cannot be retrieved later. |
| `MUX_TOOL_INPUT_FILTER_EXCLUDE` | `filter_exclude` | boolean | When true, lines matching 'filter' are excluded instead of kept. Requires 'filter' to be set. |
| `MUX_TOOL_INPUT_MIN_COMPLETED` | `min_completed` | number | Number of awaited tasks that must complete before this call returns. Defaults to 1, so by default task_await returns as soon as the FIRST awaited task completes, letting you act on it while the rest keep running. The result still includes every task complete at that moment plus current status (running/queued) for the rest. Tasks that have not yet completed keep running and remain re-awaitable on a later task_await call. Raise this (e.g. set it to the total number of awaited tasks) when you genuinely need more before proceeding — for example best-of-N synthesis that must compare every candidate. Clamped to the number of awaited tasks; values above that behave like 'wait for all'. |
| `MUX_TOOL_INPUT_TASK_IDS_<INDEX>` | `task_ids[<INDEX>]` | string | List of task IDs or workflow run IDs to await — use only real IDs returned by prior task, bash, workflow_run, or task_list tool results; never fabricate an ID. When omitted, waits for all active descendant tasks and workflow runs of the current workspace. |
| `MUX_TOOL_INPUT_TASK_IDS_COUNT` | `task_ids.length` | number | Number of elements in task_ids (List of task IDs or workflow run IDs to await — use only real IDs returned by prior task, bash, workflow_run, or task_list tool results; never fabricate an ID. When omitted, waits for all active descendant tasks and workflow runs of the current workspace.) |
| `MUX_TOOL_INPUT_TASK_IDS_<INDEX>` | `task_ids[<INDEX>]` | string | List of task IDs or workflow run IDs to await — use only real IDs returned by prior task, bash, workflow_run, or task_list tool results; never fabricate an ID. When omitted, waits for active descendant tasks and workflow runs of the current workspace, excluding workflow-owned sub-agents and their background bash tasks because those results are consumed through workflow runs. |
| `MUX_TOOL_INPUT_TASK_IDS_COUNT` | `task_ids.length` | number | Number of elements in task_ids (List of task IDs or workflow run IDs to await — use only real IDs returned by prior task, bash, workflow_run, or task_list tool results; never fabricate an ID. When omitted, waits for active descendant tasks and workflow runs of the current workspace, excluding workflow-owned sub-agents and their background bash tasks because those results are consumed through workflow runs.) |
| `MUX_TOOL_INPUT_TIMEOUT_SECS` | `timeout_secs` | number | Maximum time to wait in seconds for each task. For bash tasks, this waits for NEW output (or process exit). If exceeded, the result returns status=queued\|running\|awaiting_report (task is still active). Defaults to 600 seconds (10 minutes) if not specified. Set to 0 for a non-blocking status check. |

</details>
Expand Down
6 changes: 3 additions & 3 deletions src/common/utils/tools/toolDefinitions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -430,7 +430,7 @@ export const TaskAwaitToolArgsSchema = z
.nullish()
.describe(
"List of task IDs or workflow run IDs to await — use only real IDs returned by prior task, bash, workflow_run, or task_list tool results; never fabricate an ID. " +
"When omitted, waits for all active descendant tasks and workflow runs of the current workspace."
"When omitted, waits for active descendant tasks and workflow runs of the current workspace, excluding workflow-owned sub-agents and their background bash tasks because those results are consumed through workflow runs."
),
filter: z
.string()
Expand Down Expand Up @@ -1516,7 +1516,7 @@ export const TOOL_DEFINITIONS = {
"\n\nIMPORTANT: Do not call task_await in the same parallel tool-call batch as task or bash — " +
"the taskId is not available until the spawning tool returns. " +
"Always wait for the task/bash tool result first, then call task_await in a subsequent step. " +
"When omitting task_ids to await all active tasks/workflows, ensure at least one background task or workflow was already spawned in a prior step. " +
"When omitting task_ids to await active tasks/workflows, ensure at least one background task or workflow was already spawned in a prior step. Omitted task_ids exclude workflow-owned sub-agents and their background bash tasks because those results are consumed through workflow runs. " +
"\n\nAgent tasks and workflow runs return reports when completed. " +
"Bash tasks return incremental output while running and a final reportMarkdown when they exit. " +
"For bash tasks, you may optionally pass filter/filter_exclude to include/exclude output lines by regex. " +
Expand All @@ -1542,7 +1542,7 @@ export const TOOL_DEFINITIONS = {
task_list: {
description:
"List descendant tasks for the current workspace, including status + metadata. " +
"This includes sub-agent tasks and background bash tasks. " +
"This includes sub-agent tasks and background bash tasks, but omits workflow-owned sub-agents (and their background bash tasks) whose reports are consumed through their workflow run. " +
"Use this after compaction or interruptions to rediscover which tasks are still active. " +
"This is a discovery tool, NOT a waiting mechanism. If the current request actually depends on a task's output, call task_await with the specific task IDs you need; do not await all active tasks just because they appear here.",
schema: TaskListToolArgsSchema,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4436,8 +4436,8 @@ export const BUILTIN_SKILL_FILES: Record<string, Record<string, string>> = {
"| `MUX_TOOL_INPUT_FILTER` | `filter` | string | Optional regex to filter bash task output lines. By default, only matching lines are returned. When filter_exclude is true, matching lines are excluded instead. Non-matching lines are discarded and cannot be retrieved later. |",
"| `MUX_TOOL_INPUT_FILTER_EXCLUDE` | `filter_exclude` | boolean | When true, lines matching 'filter' are excluded instead of kept. Requires 'filter' to be set. |",
"| `MUX_TOOL_INPUT_MIN_COMPLETED` | `min_completed` | number | Number of awaited tasks that must complete before this call returns. Defaults to 1, so by default task_await returns as soon as the FIRST awaited task completes, letting you act on it while the rest keep running. The result still includes every task complete at that moment plus current status (running/queued) for the rest. Tasks that have not yet completed keep running and remain re-awaitable on a later task_await call. Raise this (e.g. set it to the total number of awaited tasks) when you genuinely need more before proceeding — for example best-of-N synthesis that must compare every candidate. Clamped to the number of awaited tasks; values above that behave like 'wait for all'. |",
"| `MUX_TOOL_INPUT_TASK_IDS_<INDEX>` | `task_ids[<INDEX>]` | string | List of task IDs or workflow run IDs to await — use only real IDs returned by prior task, bash, workflow_run, or task_list tool results; never fabricate an ID. When omitted, waits for all active descendant tasks and workflow runs of the current workspace. |",
"| `MUX_TOOL_INPUT_TASK_IDS_COUNT` | `task_ids.length` | number | Number of elements in task_ids (List of task IDs or workflow run IDs to await — use only real IDs returned by prior task, bash, workflow_run, or task_list tool results; never fabricate an ID. When omitted, waits for all active descendant tasks and workflow runs of the current workspace.) |",
"| `MUX_TOOL_INPUT_TASK_IDS_<INDEX>` | `task_ids[<INDEX>]` | string | List of task IDs or workflow run IDs to await — use only real IDs returned by prior task, bash, workflow_run, or task_list tool results; never fabricate an ID. When omitted, waits for active descendant tasks and workflow runs of the current workspace, excluding workflow-owned sub-agents and their background bash tasks because those results are consumed through workflow runs. |",
"| `MUX_TOOL_INPUT_TASK_IDS_COUNT` | `task_ids.length` | number | Number of elements in task_ids (List of task IDs or workflow run IDs to await — use only real IDs returned by prior task, bash, workflow_run, or task_list tool results; never fabricate an ID. When omitted, waits for active descendant tasks and workflow runs of the current workspace, excluding workflow-owned sub-agents and their background bash tasks because those results are consumed through workflow runs.) |",
"| `MUX_TOOL_INPUT_TIMEOUT_SECS` | `timeout_secs` | number | Maximum time to wait in seconds for each task. For bash tasks, this waits for NEW output (or process exit). If exceeded, the result returns status=queued\\|running\\|awaiting_report (task is still active). Defaults to 600 seconds (10 minutes) if not specified. Set to 0 for a non-blocking status check. |",
"",
"</details>",
Expand Down
11 changes: 11 additions & 0 deletions src/node/services/subagentReportArtifacts.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ export interface SubagentReportArtifactIndexEntry {
title?: string;
/** Full ancestor chain (parent first). Used for descendant scope checks after cleanup. */
ancestorWorkspaceIds: string[];
/** Ancestors for which this child is owned by a workflow step. */
workflowOwnedAncestorWorkspaceIds?: string[];
structuredOutput?: unknown;
/** Estimated token count of delivered report markdown (~4 chars/token). */
reportTokenEstimate?: number;
Expand Down Expand Up @@ -136,6 +138,7 @@ export async function readSubagentReportArtifact(
thinkingLevel?: unknown;
title?: unknown;
ancestorWorkspaceIds?: unknown;
workflowOwnedAncestorWorkspaceIds?: unknown;
structuredOutput?: unknown;
reportMarkdown?: unknown;
};
Expand All @@ -151,6 +154,10 @@ export async function readSubagentReportArtifact(
typeof obj.model === "string" && obj.model.trim().length > 0 ? obj.model.trim() : undefined;
const thinkingLevel = coerceThinkingLevel(obj.thinkingLevel);

const workflowOwnedAncestorWorkspaceIds = isStringArray(obj.workflowOwnedAncestorWorkspaceIds)
? obj.workflowOwnedAncestorWorkspaceIds
: undefined;

if (meta) {
// Trust the index file for metadata (versioned), but allow per-task file to override title.
return {
Expand Down Expand Up @@ -188,6 +195,7 @@ export async function readSubagentReportArtifact(
thinkingLevel,
title,
ancestorWorkspaceIds,
workflowOwnedAncestorWorkspaceIds,
structuredOutput: obj.structuredOutput,
reportMarkdown,
};
Expand Down Expand Up @@ -234,6 +242,7 @@ export async function upsertSubagentReportArtifact(params: {
model?: string;
/** Task-level thinking/reasoning level used when running the sub-agent (optional for legacy entries). */
thinkingLevel?: ThinkingLevel;
workflowOwnedAncestorWorkspaceIds?: string[];
structuredOutput?: unknown;
title?: string;
nowMs?: number;
Expand Down Expand Up @@ -272,6 +281,7 @@ export async function upsertSubagentReportArtifact(params: {
thinkingLevel,
title: params.title,
ancestorWorkspaceIds: params.ancestorWorkspaceIds,
workflowOwnedAncestorWorkspaceIds: params.workflowOwnedAncestorWorkspaceIds,
structuredOutput: params.structuredOutput,
reportMarkdown: params.reportMarkdown,
},
Expand All @@ -296,6 +306,7 @@ export async function upsertSubagentReportArtifact(params: {
model,
thinkingLevel,
title: params.title,
workflowOwnedAncestorWorkspaceIds: params.workflowOwnedAncestorWorkspaceIds,
structuredOutput: params.structuredOutput,
ancestorWorkspaceIds: params.ancestorWorkspaceIds,
};
Expand Down
Loading
Loading