Skip to content

Conversation

@qyinm
Copy link

@qyinm qyinm commented Dec 19, 2025

Closes #3768.

Summary

This PR enables the use of dynamic toolsets in Temporal workflows by allowing toolsets to be passed to agent.run() at runtime, provided they are instances of TemporalWrapperToolset.

Changes

  • Modified TemporalAgent: Updated _temporal_overrides to accept runtime toolsets if they are properly wrapped.
  • Added Test: Created tests/test_temporal_dynamic.py to verify that a TemporalFunctionToolset can be successfully passed and executed dynamically within a workflow.

Rationale

As discussed in #3768, this change allows for:

  • Cross-agent tool registration.
  • More flexible dynamic agent patterns.
  • Strict enforcement of Temporal's determinism requirements (by ensuring all tools are executed as Activities).

@qyinm qyinm force-pushed the add-allow-cross-agent-tool-registration branch from c733278 to 9a6fe3b Compare December 19, 2025 08:42
@qyinm qyinm marked this pull request as ready for review December 19, 2025 08:52

from ...exceptions import UserError
from ._agent import TemporalAgent
from ._function_toolset import TemporalFunctionToolset
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This feature should work for any toolset, so we need to export the other wrappers (MCP etc) as well

in_workflow = workflow.in_workflow()

if toolsets:
if in_workflow and any(not isinstance(t, TemporalWrapperToolset) for t in toolsets):
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  • CombinedToolsets and others that don't require temporal wrappers are fine, so we should look at the ones covered by temporalize_toolset
  • We should look down the hierarchy of toolsets using toolset.visit(), if we find a temporal wrapper, we know we don't need to look at its children, but otherwise we error if we encountered an unwrapped toolset

'Model cannot be set at agent run time inside a Temporal workflow, it must be set at agent creation time.'
)
if toolsets is not None:
if toolsets is not None and any(not isinstance(t, TemporalWrapperToolset) for t in toolsets):
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same as above; the check is not precise enough

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should be in the existing test file

activity_name_prefix='shared_tools',
activity_config=ActivityConfig(start_to_close_timeout=timedelta(minutes=1)),
tool_activity_config={},
deps_type=type(None),
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These 4 args should not be required

# We use a known name "test_agent" so the dynamic agent can share it.
base_model = TestModel()
base_agent = Agent(base_model, name='test_agent')
base_temporal_agent = TemporalAgent(base_agent)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I want to also support the same kind of pre-registering we're adding in #3537 for models, so you'd pass toolsets={'funcs': toolset, 'other': ...} and then you can pass run(toolsets=['funcs']) or run(toolsets=[toolset]) later, in addition to the instance you've pre-wrapped yourself.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In this scenario, we should make sure that TemporalAgent.toolset_activity_config and TemporalAgent.tools_activity_config work for toolsets that are not manually wrapped like that, as otherwise the user wouldn't have a way of specifying activity config

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We'll need docs! See #3537 for an example

@DouweM DouweM self-assigned this Dec 19, 2025
@qyinm qyinm closed this Dec 20, 2025
@qyinm qyinm force-pushed the add-allow-cross-agent-tool-registration branch from 9a6fe3b to ad5ba4f Compare December 20, 2025 05:10
@qyinm qyinm reopened this Dec 20, 2025
…meters optional

- Fix undefined '_model' attribute by using '_temporal_model'
- Add 'model' parameter to '_temporal_overrides' with 'using_model' support
- Skip model override outside workflow to allow direct model parameter usage
- Add 'force' parameter for toolsets property compatibility
- Make TemporalDynamicToolset __init__ parameters optional to match temporalize_toolset signature
@qyinm
Copy link
Author

qyinm commented Dec 20, 2025

@DouweM I've addressed all review feedback:

Ready for re-review.

@qyinm qyinm requested a review from DouweM December 20, 2025 16:10
@qyinm qyinm force-pushed the add-allow-cross-agent-tool-registration branch from feab98e to 2064ceb Compare December 20, 2025 23:25
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Temporal: allow cross agent tool registration

2 participants