You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
[Proposal] Optional lead/subagent scope for config-declared middlewares
#7592
Would it make sense to add an optional scope selector to extensions.middlewares for operators who use class-path configuration?
A concrete use case would be attaching a custom conversation-level observer only to the lead agent, while attaching a worker-specific observer only to subagents. Today, a configured entry is instantiated in both chains. An operator can instead package the middleware as an extension, but cannot express this choice directly in the existing class-path configuration.
This is a proposed configuration convenience, not a report of a production incident or a claim that DeerFlow lacks scoped middleware altogether.
Current behavior and existing alternative
I checked upstream main at c46906aa41870564ee107d4d2f456f323839812b:
ConfiguredMiddlewareSpec accepts class and kwargs; unknown fields are rejected.
The lead builder and subagent runtime builder both call load_configured_extension_middlewares without a scope argument.
Packaged extensions already expose AgentScope, AgentBuildContext.scope, and MiddlewarePlacement.scope. That is a supported alternative and may be the preferred long-term route.
The question is whether the existing lightweight configuration path should offer the same coarse selection, or whether operators should be directed to packaged extensions whenever they need it.
Proposed configuration
If extending the configuration path is welcome, I suggest an optional apply_to field on object entries, accepting exactly both, lead, or subagent:
These class names are illustrative, not bundled classes. Omitted apply_to, including legacy string entries, would mean both. The same values would work in the existing JSON object representation. This would not add a new configuration source or change configuration precedence.
Behavioral contract
The host supplies the scope from the lead/subagent builder. It is not inferred from an agent name or accepted from user message content.
Validate every entry's shape and scope during configuration validation, including entries excluded from a particular chain. Invalid values, nulls, lists, and unknown fields fail validation.
For a valid excluded entry, skip class resolution and construction in that chain. For a selected entry, preserve current import, subclass, and constructor failure behavior.
Preserve the relative order of selected entries and their current insertion point. Keep constructor kwargs unchanged; apply_to is host metadata, not a constructor argument.
Keep fresh middleware instances per build. Do not change built-in middleware, packaged-extension placement, permissions, or runtime safety checks.
Limit automatic scope selection to the standard lead/subagent paths that already load these entries. Do not silently expand it to other agent factory APIs.
Implementation and validation
The intended change is small: extend the existing config model, add explicit scope selection to the shared loader, and pass the appropriate scope at its two current call sites. No dependency, frontend, database, or external service is needed.
Tests would cover legacy strings and objects, all three scopes, invalid values, order and kwargs preservation, skipped import/constructor side effects, selected-entry failures, fresh instances, and actual lead/subagent builder wiring. Existing configuration reload tests and backend lint/test checks would also run. These are planned checks; no implementation or test result is being claimed here.
Named-subagent filters, per-request overrides, dynamic predicates, placement changes, and a middleware management UI are outside this proposal.
Feedback requested
Is this configuration convenience useful enough to support, or should scoped middleware exclusively use packaged extensions?
If supported, is apply_to: both | lead | subagent the right shape and terminology?
Is filtering before class resolution/construction the desired behavior for excluded entries?
I would like to align on that boundary before implementing it. If this overlaps with ongoing work, please point me to the existing proposal.
reacted with thumbs up emoji reacted with thumbs down emoji reacted with laugh emoji reacted with hooray emoji reacted with confused emoji reacted with heart emoji reacted with rocket emoji reacted with eyes emoji
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Motivation
Would it make sense to add an optional scope selector to
extensions.middlewaresfor operators who use class-path configuration?A concrete use case would be attaching a custom conversation-level observer only to the lead agent, while attaching a worker-specific observer only to subagents. Today, a configured entry is instantiated in both chains. An operator can instead package the middleware as an extension, but cannot express this choice directly in the existing class-path configuration.
This is a proposed configuration convenience, not a report of a production incident or a claim that DeerFlow lacks scoped middleware altogether.
Current behavior and existing alternative
I checked upstream
mainatc46906aa41870564ee107d4d2f456f323839812b:ConfiguredMiddlewareSpecacceptsclassandkwargs; unknown fields are rejected.load_configured_extension_middlewareswithout a scope argument.AgentScope,AgentBuildContext.scope, andMiddlewarePlacement.scope. That is a supported alternative and may be the preferred long-term route.The question is whether the existing lightweight configuration path should offer the same coarse selection, or whether operators should be directed to packaged extensions whenever they need it.
Proposed configuration
If extending the configuration path is welcome, I suggest an optional
apply_tofield on object entries, accepting exactlyboth,lead, orsubagent:These class names are illustrative, not bundled classes. Omitted
apply_to, including legacy string entries, would meanboth. The same values would work in the existing JSON object representation. This would not add a new configuration source or change configuration precedence.Behavioral contract
apply_tois host metadata, not a constructor argument.Implementation and validation
The intended change is small: extend the existing config model, add explicit scope selection to the shared loader, and pass the appropriate scope at its two current call sites. No dependency, frontend, database, or external service is needed.
Tests would cover legacy strings and objects, all three scopes, invalid values, order and kwargs preservation, skipped import/constructor side effects, selected-entry failures, fresh instances, and actual lead/subagent builder wiring. Existing configuration reload tests and backend lint/test checks would also run. These are planned checks; no implementation or test result is being claimed here.
Named-subagent filters, per-request overrides, dynamic predicates, placement changes, and a middleware management UI are outside this proposal.
Feedback requested
apply_to: both | lead | subagentthe right shape and terminology?I would like to align on that boundary before implementing it. If this overlaps with ongoing work, please point me to the existing proposal.
Related work: #5311, #5312.
All reactions