Skip to content

WIP: Temporal Agent #2225

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 1 commit into
base: main
Choose a base branch
from
Draft

WIP: Temporal Agent #2225

wants to merge 1 commit into from

Conversation

DouweM
Copy link
Contributor

@DouweM DouweM commented Jul 17, 2025

Closes #1975

@DouweM DouweM self-assigned this Jul 17, 2025
Copy link

github-actions bot commented Jul 17, 2025

Docs Preview

commit: 2abccad
Preview URL: https://67ad3d57-pydantic-ai-previews.pydantic.workers.dev

@mattbrandman
Copy link

I'm so excited for this to be natively supported

@nir-litt
Copy link

Thank you for taking the time to look into native temporal support - this is a topic I’m really interested in seeing progress on.

One key feature I’d love to see is support for HITL (Human-in-the-Loop) during tool calls when using temporal and agents. My suggestion on how to achieve that (and not being to specific for HITL) is to pause the workflow before a tool call waiting on a condition for a signal. This will allow, among other things, to wait for human input.

Currently, tool calls are handled like this:

async def call_tool(
    self, name: str, tool_args: dict[str, Any], ctx: RunContext[AgentDepsT], tool: ToolsetTool[AgentDepsT]
) -> Any:
    serialized_run_context = self.serialize_run_context(ctx)
    return await workflow.execute_activity(
        activity=self.call_tool_activity,
        arg=FunctionCallToolParams(name=name, tool_args=tool_args, serialized_run_context=serialized_run_context),
        **self.temporal_settings.__dict__,
    )

To add the wait support, we can do something like:
(This example is a bit abstract - we will have to understand (at least):

  • how to pass the self.allow_tool_call from the workflow to this class or effect it with some callback instead of just setting it
  • pass all the data of the tool call for the handler to be able to decide which action to take)
async def call_tool(
    self, name: str, tool_args: dict[str, Any], ctx: RunContext[AgentDepsT], tool: ToolsetTool[AgentDepsT]
) -> Any:
    # --- ADDED: tool call pause using signal and wait_condition ---
    await workflow.wait_condition(lambda: self.allow_tool_call)
    # --- END ADDED CODE ---
    serialized_run_context = self.serialize_run_context(ctx)
    activity_result =  await workflow.execute_activity(
        activity=self.call_tool_activity,
        arg=FunctionCallToolParams(name=name, tool_args=tool_args, serialized_run_context=serialized_run_context),
        **self.temporal_settings.__dict__,
    )
    # --- ADDED: tool call reset state ---
    self.allow_tool_call = False
    return activity_result
    # --- END ADDED CODE ---

This will allow users to define their workflow something like:

@workflow.signal
def approve_tool_call(self):
    ... # some code to determine the tool is OK to run
    self.allow_tool_call = True

This way, the workflow will pause at the tool call and only continue once the signal is approved.

of course this would be optional and the default ,that can be overwritten by the user, will be to approve the request

Appreciate the ongoing work!

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.

Native temporal support
3 participants