Skip to content

fix(agents): prevent parent authorized_imports from leaking into managed agents on from_dict#2218

Open
VANDRANKI wants to merge 3 commits intohuggingface:mainfrom
VANDRANKI:fix/from-dict-authorized-imports-leak
Open

fix(agents): prevent parent authorized_imports from leaking into managed agents on from_dict#2218
VANDRANKI wants to merge 3 commits intohuggingface:mainfrom
VANDRANKI:fix/from-dict-authorized-imports-leak

Conversation

@VANDRANKI
Copy link
Copy Markdown

Summary

When a CodeAgent with managed sub-agents is deserialized via from_dict(), the parent agent's additional_authorized_imports overwrites every child agent's own import allowlist. Reproducer from issue #1849:

sub_agent = CodeAgent(
    tools=[], model=model,
    additional_authorized_imports=['sympy'],
    name='sympy_agent',
)
main_agent = CodeAgent(
    tools=[], model=model,
    additional_authorized_imports=['numpy'],
    managed_agents=[sub_agent],
)
restored = CodeAgent.from_dict(main_agent.to_dict())
# 'sympy' not in restored.managed_agents['sympy_agent'].authorized_imports  <- BUG

Root cause

CodeAgent.from_dict() builds code_agent_kwargs containing additional_authorized_imports from the current agent's serialized dict, then calls super().from_dict(agent_dict, **code_agent_kwargs). MultiStepAgent.from_dict() forwarded those kwargs unchanged to every managed agent via agent_class.from_dict(managed_agent_dict, **kwargs). Because the parent's additional_authorized_imports is in kwargs, it overwrites the child's own value.

Fix

In MultiStepAgent.from_dict(), filter out CodeAgent-specific keys (additional_authorized_imports, executor_type, executor_kwargs, max_print_outputs_length, code_block_tags) before passing kwargs to managed agents. Generic overrides like model= are still forwarded tree-wide.

This preserves the existing behavior where callers can do from_dict(d, model=new_model) to inject a model into the whole agent tree, while ensuring each agent's import allowlist is always reconstructed from its own serialized data.

Test

Added test_from_dict_managed_agent_authorized_imports_not_leaked in TestCodeAgent that verifies a child agent with ['sympy', 'math'] imports retains them after a parent with ['numpy', 'pandas'] is deserialized.

Fixes #1849

…gs in from_dict

When a CodeAgent with managed agents is deserialized via from_dict(),
CodeAgent.from_dict() extracts additional_authorized_imports from the
current agent's dict and passes them in code_agent_kwargs to
super().from_dict(). MultiStepAgent.from_dict() then forwards those same
kwargs to every managed agent's from_dict() call. Because
code_agent_kwargs.update(kwargs) runs before the managed agent's own
authorized_imports are set, the parent's import allowlist overwrites the
child's own.

Fix: remove additional_authorized_imports from the initial code_agent_kwargs
dict and re-apply it from the agent's own serialized data after update(kwargs),
so each agent always reconstructs with its own import allowlist regardless
of what the parent propagated.

Fixes: huggingface#1849
…ged agents

When a CodeAgent with managed sub-agents is deserialized via from_dict(),
CodeAgent.from_dict() builds code_agent_kwargs that includes
additional_authorized_imports from the parent's own serialized dict, then
calls super().from_dict(agent_dict, **code_agent_kwargs). MultiStepAgent.-
from_dict() forwarded those kwargs unchanged to every managed agent, causing
each child's additional_authorized_imports to be overwritten by the parent's.

Fix: in MultiStepAgent.from_dict(), filter out CodeAgent-specific keys
(additional_authorized_imports, executor_type, executor_kwargs,
max_print_outputs_length, code_block_tags) before passing kwargs to managed
agents. Generic overrides like model= are still propagated tree-wide.

This preserves the ability to call from_dict(dict, model=new_model) and
have the new model apply to all agents in the tree, while ensuring each
agent's import allowlist and executor config are always reconstructed from
its own serialized data.

Fixes: huggingface#1849
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

BUG: MultiStepAgent.from_dict() passes **kwargs to managed agents, causing child agent configurations to be overridden

1 participant