mirror of
https://github.com/agent0ai/agent-zero.git
synced 2026-07-09 17:08:29 +00:00
Block document query in parallel calls
Reject document_query during parallel tool-call normalization before worker jobs are started. Add prompt guidance so the model avoids batching document_query, and update DOX plus regressions for the new sequential-only contract.
This commit is contained in:
parent
ec3c4cf81b
commit
4714b5dcb9
6 changed files with 21 additions and 0 deletions
|
|
@ -31,6 +31,7 @@ CHILD_PARALLEL_TOOL_NAME_KEY = "parallel_tool_name"
|
|||
DEFAULT_MAX_CALLS = 8
|
||||
DEFAULT_TIMEOUT_SECONDS = 300
|
||||
POLL_INTERVAL_SECONDS = 0.5
|
||||
DISALLOWED_PARALLEL_TOOLS = {"document_query"}
|
||||
|
||||
TERMINAL_STATES = {"success", "error", "cancelled", "timeout"}
|
||||
JobState = Literal["pending", "running", "success", "error", "cancelled", "timeout"]
|
||||
|
|
@ -93,6 +94,10 @@ def normalize_parallel_tool_calls(raw_calls: Any) -> list[NormalizedToolCall]:
|
|||
|
||||
if tool_name == "parallel":
|
||||
raise ValueError("`parallel` cannot be nested inside another `parallel` call.")
|
||||
if tool_name in DISALLOWED_PARALLEL_TOOLS:
|
||||
raise ValueError(
|
||||
f"`{tool_name}` cannot be used inside `parallel`; call it sequentially."
|
||||
)
|
||||
|
||||
calls.append(
|
||||
NormalizedToolCall(
|
||||
|
|
|
|||
|
|
@ -24,6 +24,7 @@
|
|||
- Helper modules own reusable framework APIs and must preserve public callers unless all callers, tests, and docs are updated together.
|
||||
- Wrapped tool-call items must use the same shape as normal tool calls: a tool name plus arguments.
|
||||
- Normalization accepts full agent-reply-shaped objects when `tool_name` and `tool_args` are present; non-contract planning fields such as `thoughts` or `headline` are ignored.
|
||||
- Normalization rejects `document_query` inside `parallel` because document parsing and Q&A fan out into heavier worker/model paths that must run sequentially.
|
||||
- `call_subordinate` jobs run in isolated child chat contexts tagged with parent-chat metadata; they must not be added to the scheduler task list and may use normal child-chat tools, including `parallel`.
|
||||
- Direct tool jobs run in isolated background contexts and are blocked from recursively invoking `parallel`.
|
||||
- Parent-visible child log items are created for each wrapped call so the WebUI can inspect concurrent children separately while the wrapper result remains model-history-only.
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@ Batch all independent calls that are ready now into one `tool_calls` list, even
|
|||
Rules:
|
||||
- do not use for one simple call, dependent steps, ordered steps, shared mutable state, or state/tool-availability changes that must happen in the parent context
|
||||
- never nest `parallel`
|
||||
- Never include `document_query` in `tool_calls`; it is too heavy for parallel workers, so call it sequentially.
|
||||
- `call_subordinate` inside `parallel` starts an isolated child chat under the parent chat, not a scheduler task
|
||||
- use `wait: false` only when you will collect results later with `job_ids`
|
||||
- if extras list running or ready parallel jobs, collect them before final synthesis
|
||||
|
|
|
|||
|
|
@ -110,6 +110,18 @@ def test_normalize_parallel_tool_calls_rejects_nested_parallel() -> None:
|
|||
)
|
||||
|
||||
|
||||
def test_normalize_parallel_tool_calls_rejects_document_query() -> None:
|
||||
with pytest.raises(ValueError, match="document_query.*parallel"):
|
||||
parallel_tools.normalize_parallel_tool_calls(
|
||||
[
|
||||
{
|
||||
"tool_name": "document_query",
|
||||
"tool_args": {"document": "/tmp/report.pdf"},
|
||||
}
|
||||
]
|
||||
)
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_parallel_jobs_extras_lists_running_and_ready_jobs() -> None:
|
||||
agent = _FakeAgent()
|
||||
|
|
|
|||
|
|
@ -93,3 +93,4 @@ def test_parallel_prompt_encourages_mixed_independent_batches() -> None:
|
|||
assert "planning fields like `thoughts` or `headline` are ignored" in prompt
|
||||
assert "even when they use different tools" in prompt
|
||||
assert "Do not split by tool type" in prompt
|
||||
assert "Never include `document_query`" in prompt
|
||||
|
|
|
|||
|
|
@ -22,6 +22,7 @@
|
|||
- Wrapped items use the same schema as normal tool calls: a tool name plus arguments.
|
||||
- The tool is intended for independent calls only; dependent operations remain sequential.
|
||||
- Independent calls should share one batch even when they use different tools; split only for dependencies, ordering, shared mutable state, or parent-context state/tool-availability changes.
|
||||
- `document_query` is intentionally excluded from wrapped calls because it is too heavy for parallel workers and must be called sequentially.
|
||||
- `action="start"` starts calls and optionally waits according to `wait`.
|
||||
- `action="await"` waits for requested job IDs until completion or `timeout`; timeout returns running job handles without canceling them.
|
||||
- `action="collect"` returns completed job results without waiting.
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue