Skip to content

Stop Chat UI workflow polling when a session has no active workflows #162

Description

Problem

The built-in Chat UI calls GET /agents/{slug}/workflows every 3 seconds while the page is visible and workflow support is enabled. Polling continues after every workflow in the current agent/session has reached a terminal state, producing repeated Functions executions and unnecessary Durable status queries.

The UI already recognizes terminal states (Completed, Failed, Canceled, and Terminated) and avoids re-rendering an unchanged terminal card, but the interval itself continues indefinitely.

Current implementation

  • src/azure_functions_agents/public/index.html
    • TERMINAL_WORKFLOW_STATES defines the terminal set.
    • pollWorkflowsOnce() fetches the session-wide /workflows endpoint and upserts every returned envelope.
    • startWorkflowPolling() creates an unconditional 3-second setInterval.
    • polling currently stops only for unsupported workflow endpoints, hidden tabs, session/app changes, or history replay.
  • src/azure_functions_agents/workflows/tools.py
    • fetch_session_workflows() calls Durable get_status_all(), filters by (workflow_agent_slug, session_id), sorts, and returns up to the configured result cap.

Because /workflows is session-wide rather than one request per workflow, the useful optimization is to stop the whole timer when the latest successful response contains no non-terminal workflow—not merely to skip individual terminal cards.

Proposed behavior

  1. Continue polling every 3 seconds while at least one returned workflow is non-terminal.
  2. After a successful response where every workflow is terminal (and terminal notification processing has been queued), stop the interval.
  3. Perform an initial one-shot poll on page/session restore so active workflows are rediscovered.
  4. Restart polling when a new workflow may have been created, including after a chat turn that calls start_workflow or after a relevant app/session transition.
  5. Preserve current hidden-tab, epoch, capability-probe, failure-warning, and terminal auto-notification behavior.

Design considerations

  • startWorkflowPolling() is currently called before chat submission. If an immediate poll sees only old terminal workflows and stops, a workflow started by that chat turn could be missed. Restart should therefore occur after the turn completes or when a successful start_workflow tool result is observed.
  • A workflow may be started externally or from another browser tab using the same session. Permanent idle shutdown would not discover it without another UI event. Decide whether to accept event-driven restart or use a low-frequency idle backoff as a safety probe.
  • Empty workflow lists should stop high-frequency polling after the initial capability/session probe.
  • Completion notifications must still fire exactly once for fast workflows that start and finish between poll intervals.
  • The endpoint currently calls app-wide Durable get_status_all() before filtering. A separate follow-up may optimize backend querying if SDK support for instance-prefix/status filters is available.

Acceptance criteria

  • No repeated 3-second /workflows requests after the current session has no non-terminal workflows.
  • Polling restarts reliably for a newly started workflow in the same Chat UI session.
  • Active workflows continue updating at the current cadence.
  • Completed, Failed, Canceled, and Terminated all stop active polling when no other workflow remains active.
  • Terminal auto-notifications still occur once and are not lost during the stop transition.
  • Page visibility, session switching, history replay, unsupported endpoint handling, and transient failure behavior remain correct.
  • Tests cover all-terminal, mixed active/terminal, empty list, fast completion, and restart-after-chat-start scenarios.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions