Skip to content
Open
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
36 changes: 35 additions & 1 deletion docs/agents/index.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -619,16 +619,19 @@ tools:
remove:
- image_.*
- file_edit_.*
- task
- task_apply_git_patch
- task_list
- task_send_message
- task_terminate
- task_workspace_lifecycle
- workflow_run
- workflow_resume
---

You are in Explore mode (read-only).

You may use `task` to delegate independent read-only investigation only to `explore` agents. Do not delegate to other agents.

=== CRITICAL: READ-ONLY MODE - NO FILE MODIFICATIONS ===

- You MUST NOT manually create, edit, delete, move, copy, or rename tracked files.
Expand Down Expand Up @@ -670,6 +673,37 @@ Do not emit text responses. Call the `propose_name` tool immediately.

</Accordion>

### Research Verifier (internal)

**Read-only leaf agent for adversarial research verification**

<Accordion title="View research_verifier.md">

```md
---
name: Research Verifier
description: Read-only leaf agent for adversarial research verification
base: explore
ui:
hidden: true
subagent:
runnable: false
workflow_runnable: true
tools:
remove:
- task
- task_await
---

You are a read-only leaf verifier.

- Verify the delegated claim directly with the available research tools.
- Do not delegate work or start another workflow.
- Return only the requested structured result.
```

</Accordion>

{/* END BUILTIN_AGENTS */}

## Related Docs
Expand Down
9 changes: 9 additions & 0 deletions src/browser/features/Settings/Sections/TasksSection.agents.ts
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,15 @@ export const FALLBACK_AGENTS: AgentDefinitionDescriptor[] = [
subagentRunnable: true,
base: "exec",
},
{
id: "research_verifier",
scope: "built-in",
name: "Research Verifier",
description: "Read-only leaf agent for adversarial research verification",
uiSelectable: false,
subagentRunnable: false,
base: "explore",
},
{
id: "name_workspace",
scope: "built-in",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ describe("FALLBACK_AGENTS", () => {
expect(fallbackAgentIds).toContain("desktop");
expect(fallbackAgentIds).toContain("name_workspace");
expect(fallbackAgentIds).toContain("dream");
expect(fallbackAgentIds).toContain("research_verifier");
});
});

Expand Down
14 changes: 14 additions & 0 deletions src/common/utils/agentTools.test.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,25 @@
import { describe, expect, it } from "@jest/globals";
import {
isExecLikeEditingCapableInResolvedChain,
isExploreLikeInResolvedChain,
isToolEnabledByConfigs,
isToolEnabledInResolvedChain,
type ToolsConfig,
} from "./agentTools";

describe("isExploreLikeInResolvedChain", () => {
it("returns true for Explore and agents derived from Explore", () => {
expect(isExploreLikeInResolvedChain([{ id: "explore" }, { id: "exec" }])).toBe(true);
expect(
isExploreLikeInResolvedChain([{ id: "reviewer" }, { id: "explore" }, { id: "exec" }])
).toBe(true);
});

it("returns false when the chain does not inherit Explore", () => {
expect(isExploreLikeInResolvedChain([{ id: "reviewer" }, { id: "exec" }])).toBe(false);
});
});

describe("isExecLikeEditingCapableInResolvedChain", () => {
it("returns true when exec chain enables file_edit_insert", () => {
const agents = [{ id: "exec", tools: { add: ["file_edit_insert"] } }];
Expand Down
7 changes: 7 additions & 0 deletions src/common/utils/agentTools.ts
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,13 @@ export function isPlanLikeInResolvedChain(
return isToolEnabledInResolvedChain("propose_plan", agents, maxDepth);
}

export function isExploreLikeInResolvedChain(
agents: ReadonlyArray<{ id: AgentId }>,
maxDepth = 10
): boolean {
return agents.slice(0, maxDepth).some((agent) => agent.id === "explore");
}

export function isExecLikeEditingCapableInResolvedChain(
agents: ReadonlyArray<ToolsConfigCarrier & { id: AgentId }>,
maxDepth = 10
Expand Down
2 changes: 2 additions & 0 deletions src/common/utils/tools/tools.ts
Original file line number Diff line number Diff line change
Expand Up @@ -198,6 +198,8 @@ export interface ToolConfiguration {
onConfigChanged?: () => void;
/** Best-effort callback for recording tool-initiated model usage in session totals. */
reportModelUsage?: (event: ToolModelUsageEvent) => void;
/** Restrict task delegation to read-only Explore agents and reject full workspace turns. */
taskExploreOnly?: boolean;
/** Task orchestration for sub-agent tasks */
taskService?: TaskService;
/** Durable workflow lifecycle service for dynamic workflow tools. */
Expand Down
5 changes: 4 additions & 1 deletion src/node/builtinAgents/explore.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,16 +21,19 @@ tools:
remove:
- image_.*
- file_edit_.*
- task
- task_apply_git_patch
- task_list
- task_send_message
- task_terminate
- task_workspace_lifecycle
- workflow_run
- workflow_resume
---

You are in Explore mode (read-only).

You may use `task` to delegate independent read-only investigation only to `explore` agents. Do not delegate to other agents.

=== CRITICAL: READ-ONLY MODE - NO FILE MODIFICATIONS ===

- You MUST NOT manually create, edit, delete, move, copy, or rename tracked files.
Expand Down
20 changes: 20 additions & 0 deletions src/node/builtinAgents/research_verifier.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
---
name: Research Verifier
description: Read-only leaf agent for adversarial research verification
base: explore
ui:
hidden: true
subagent:
runnable: false
workflow_runnable: true
tools:
remove:
- task
- task_await
---

You are a read-only leaf verifier.

- Verify the delegated claim directly with the available research tools.
- Do not delegate work or start another workflow.
- Return only the requested structured result.
2 changes: 1 addition & 1 deletion src/node/builtinSkills/deep-research.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,4 +18,4 @@ workflow_run({

Default to foreground mode because the user normally needs the final report before you can answer. If the user explicitly asks you to research in the background or be notified later, pass `run_in_background: true`, report the `runId`, and end the turn; Mux will wake the workspace with the terminal workflow result.

The workflow scopes search angles, searches and fetches sources, extracts falsifiable claims, verifies claims adversarially with exec agents using their configured defaults, and synthesizes a cited report with caveats.
The workflow scopes search angles, searches and fetches sources, extracts falsifiable claims, verifies claims with workflow-only read-only agents, and synthesizes a cited report with caveats.
3 changes: 2 additions & 1 deletion src/node/builtinSkills/deep-research/workflow.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ const MAX_PARALLEL_FETCH = 5;
const MAX_PARALLEL_VERIFY = 12;

const EXPLORE_AGENT = "explore";
const RESEARCH_VERIFIER_AGENT = "research_verifier";
const EXEC_AGENT = "exec";

const SCOPE_SCHEMA = {
Expand Down Expand Up @@ -265,7 +266,7 @@ export default function workflow({ args, phase, log, agent, parallel, pipeline }
agent(buildVerifyPrompt(question, spec.claim, spec.voteIndex), {
id: stableId("verify", spec.claimIndex + "-" + spec.voteIndex, spec.claim.claim),
title: "Verify claim " + (spec.claimIndex + 1) + "." + (spec.voteIndex + 1),
agentId: EXEC_AGENT,
agentId: RESEARCH_VERIFIER_AGENT,
onRefusal: "fail",
schema: VERDICT_SCHEMA,
})
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -495,11 +495,35 @@ Custom planning instructions.
"task_terminate",
"task_workspace_lifecycle",
"workflow_run",
"workflow_resume",
],
toolPolicy
)
).toEqual(["task_await", "workflow_run"]);
).toEqual(["task", "task_await"]);
});
test("research verifier inherits research tools without orchestration tools", async () => {
using tempDir = new DisposableTempDir("agent-research-verifier-policy");
const runtime = new LocalRuntime(tempDir.path);

const verifierFrontmatter = await resolveAgentFrontmatter(
runtime,
tempDir.path,
"research_verifier"
);
const toolPolicy = resolveToolPolicyForAgent({
agents: [{ tools: verifierFrontmatter.tools }],
isSubagent: true,
disableTaskToolsForDepth: false,
});

expect(
applyToolPolicyToNames(
["task", "task_await", "workflow_run", "workflow_resume", "web_search"],
toolPolicy
)
).toEqual(["web_search"]);
});

test("same-name override: project agent with base: self extends built-in/global, not itself", async () => {
using project = new DisposableTempDir("agent-same-name");
using global = new DisposableTempDir("agent-same-name-global");
Expand Down
Loading
Loading