Skip to content

Python: Support workflow entry-state updates and per-AgentExecutor run options #8711

Open

Description

Motivation

A Foundry-hosted Workflow should be usable directly, without workflow.as_agent(). Its Responses host needs an explicit parser that converts the incoming Responses items into the start executor's input type. That parser may also need to set application-owned workflow state for this turn and pass caller-derived MAF run options to all or selected AgentExecutors.

Core currently has no public path for either operation:

  • Workflow.run(...) accepts message, responses, checkpoint_id, checkpoint_storage, tools, client_kwargs, and function_invocation_kwargs, but not a state delta or nested-agent options.
  • WorkflowContext.set_state(...) is available inside an executor, not to the host before the start executor runs. Requiring each app to pack state into its start message and add an initializer executor defeats the hosting ergonomics.
  • AgentExecutor forwards client_kwargs and function_invocation_kwargs to agent.run(...), but not options=.... Those kwargs have different semantics from MAF ChatOptions.
  • Existing workflow run kwargs are written into shared workflow state and included in checkpoints. Short-lived caller identity, call IDs, or credentials must not be passed through a channel that persists them.

Relevant code: python/packages/core/agent_framework/_workflows/_workflow.py, _workflow_context.py, and _agent_executor.py.

Requested capability (API shape open)

Provide a public workflow entry path for application-owned state updates and MAF runtime options for nested agents. For example:

await workflow.run(
    message=typed_start_input,
    state_updates={"task_id": task_id},
    agent_options=WorkflowInvocationKwargs(
        global_kwargs={"max_tokens": 500},
        executor_kwargs={"reviewer": {"temperature": 0}},
    ),
)

The exact names and whether this requires a vNext change are open. Desired semantics:

  • Apply application state updates at the turn boundary before the start executor runs; on a continuation, restore the correct checkpoint before applying the new turn's updates. Do not let callers overwrite framework-reserved state.
  • Resolve global and per-executor options by stable executor ID, then call each nested agent using its normal Agent.run(options=...) precedence over developer-owned default_options. Omitting a runtime option leaves the default intact.
  • Support both streaming and non-streaming, new input and pending responses=... (approval/user input) continuations, without treating client_kwargs as equivalent to options.
  • Specify which data is checkpointed versus request-only. Credentials and platform call IDs must not accidentally enter checkpoints or survive into a later caller's turn.
  • Preserve compatibility with existing client_kwargs and function_invocation_kwargs behavior where feasible. Checkpoint/recovery behavior should not replay stale per-request values.

Timing and current workaround

This is not a request to change core as part of the current Foundry-hosting redesign. It might belong in vNext if the correct state/option ownership requires a breaking change. Until then, a host can accept a request-aware Callable[[request], Workflow] whose developer builds a fresh workflow and sets each nested agent's default_options, and it can continue using existing client_kwargs / function_invocation_kwargs for their supported purposes. Those mechanisms do not provide general per-turn Agent.run(options=...) or pre-entry workflow state updates.

Related: #8522 (vNext caller-owned workflow checkpoints) and #7677 (restore/input/response semantics).

Activity

  1. vedantsonkar commented on Sep 24, 2026

    @vedantsonkar
    Contributor

    Hi Eduard van Valkenburg (@eavanvalkenburg) I'd like to work on this

  2. vedantsonkar commented on Sep 24, 2026

    @vedantsonkar
    Contributor

    Eduard van Valkenburg (@eavanvalkenburg) , would an additive Workflow.run(state_updates=..., agent_options=...) change, separate from the current Foundry-hosting redesign, fit this issue? We’d apply state updates after checkpoint restore and before entry work, then pass request-scoped options by stable AgentExecutor ID to Agent.run(options=...) for streaming and non-streaming runs. State updates would be checkpointed; raw agent options would not. Per-executor targeting would cover agents in the invoked workflow, not nested subworkflows.
    One compatibility question: we’d preserve existing client_kwargs and function_invocation_kwargs checkpoint replay, while letting explicitly supplied values override restored ones. Does that meet your recovery requirement, or should those legacy kwargs stop replaying too?

  3. eavanvalkenburg commented on Oct 27, 2026

    @eavanvalkenburg
    MemberAuthor

    /plan Produce a spec-first design and timing assessment for the maintainer-established workflow entry-state and per-AgentExecutor options requirement. This is not approval for the proposed additive 1.x implementation, not part of the already-shipped hosting redesign (#8742/#8747/#8748/#8966), and does not lift #8522 scheduling/ownership holds; report the smallest spec/test-only preparatory slice and what must wait for maintainer agreement or vNext. Separate durable application state deltas from request-only agent options/credentials. Define restore-before-delta-before-entry ordering for new input and pending responses, reserved-key protection, stable executor-ID targeting and invalid-target behavior, per-executor/global/default_options precedence, streaming/nonstream parity, and explicit nested-workflow boundaries. Reuse normal Agent.run(options=...) semantics rather than treating client_kwargs or function_invocation_kwargs as ChatOptions. Inventory current fresh-turn reset and continuation/checkpoint replay semantics (including the #9677 investigation and #7677 restore/input rules), then explicitly compare preserving legacy kwargs replay versus changing it; do not silently select the volunteer proposal or persist raw credentials/call IDs. Specify how request-only values are supplied again on resume and cannot leak to later callers, checkpoint serialization or recovery. Account for the request-aware fresh-workflow factory workaround and current native hosts so a narrow API does not conflict with caller-owned checkpoint redesign. Include deterministic tests for precedence, state collisions, restore/resume ordering, serialization absence of request-only values and independent callers; no live Foundry resources. Leave unassigned and non-ready while maintainers decide timing/contract; do not treat the contributor offer as implementation authorization.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    pythonUsage: [Issues, PRs], Target: Python

    Type

    No type

    Projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions