Skip to content
Learn Agentic AI12 min read0 views

Building Multi-Application Workflows with UFO: Cross-App Automation Sequences

Master cross-application automation with Microsoft UFO by building workflows that transfer data between Excel, Outlook, browsers, and desktop applications through coordinated multi-app sequences.

The Power of Cross-Application Workflows

Single-application automation is useful but limited. The real productivity gains come from workflows that span multiple applications — extracting data from a database viewer, processing it in Excel, creating a report in Word, and emailing it through Outlook. These are the workflows that consume hours of manual labor every week and are notoriously difficult to automate with traditional tools.

UFO's HostAgent architecture is specifically designed for this scenario. It manages application switching, context preservation, and data transfer between apps.

Workflow 1: Web Data to Excel Report

This workflow scrapes data from a browser and processes it in Excel:

import subprocess
import time

def run_ufo_task(task: str, timeout: int = 300):
    """Execute a single UFO task."""
    result = subprocess.run(
        ["python", "-m", "ufo", "--task", task],
        capture_output=True, text=True, timeout=timeout,
    )
    if result.returncode != 0:
        raise RuntimeError(f"UFO task failed: {result.stderr}")
    return result.stdout


def web_to_excel_report():
    """Extract web data and create an Excel report."""
    run_ufo_task(
        "In Google Chrome, select the data table on the sales "
        "dashboard and copy it to clipboard."
    )
    run_ufo_task(
        "Open Excel, create a new workbook, paste clipboard at A1. "
        "Bold the header row, auto-fit column widths, and add a "
        "Growth % column with formulas."
    )
    run_ufo_task(
        "In Excel, select Month and Revenue columns, insert a line "
        "chart, save as Monthly_Report.xlsx on the Desktop."
    )

Workflow 2: Excel Analysis to Email Summary

def excel_to_email_summary():
    """Analyze Excel data and send a summary email."""

    tasks = [
        # Open and analyze Excel data
        (
            "In Excel, open the file C:\\Reports\\Q1_Revenue.xlsx. "
            "Go to the Summary sheet. Note the total revenue value in "
            "cell D15 and the growth percentage in cell E15."
        ),
        # Select and copy key data
        (
            "In Excel, select the range A1 through E5 on the Summary "
            "sheet which contains the top 5 performers. Copy the "
            "selection to clipboard."
        ),
        # Compose email with context
        (
            "In Microsoft Outlook, create a new email. Set the To field "
            "to leadership@company.com. Set the Subject to "
            "'Q1 Revenue Summary - Top Performers'. In the email body, "
            "type 'Team,' press Enter twice, then type "
            "'Here are the Q1 revenue highlights:' press Enter twice, "
            "then paste the clipboard contents. Press Enter twice more "
            "and type 'Full report available in the shared drive.' "
            "press Enter, type 'Best regards'"
        ),
        # Send
        (
            "In Outlook, review the email and click Send."
        ),
    ]

    for i, task in enumerate(tasks, 1):
        print(f"Executing step {i}/{len(tasks)}...")
        run_ufo_task(task)
        time.sleep(2)  # Allow UI to settle between steps

Building a Workflow Orchestrator

For production use, wrap UFO tasks in an orchestrator that handles errors, retries, and logging:

import logging
from dataclasses import dataclass
from enum import Enum
from typing import Callable, Optional

logger = logging.getLogger("ufo_orchestrator")


class StepStatus(Enum):
    PENDING = "pending"
    RUNNING = "running"
    COMPLETED = "completed"
    FAILED = "failed"
    RETRYING = "retrying"


@dataclass
class WorkflowStep:
    name: str
    task: str
    timeout: int = 300
    max_retries: int = 2
    pre_condition: Optional[Callable] = None
    post_validation: Optional[Callable] = None


class UFOWorkflowOrchestrator:
    def __init__(self, workflow_name: str, steps: list[WorkflowStep]):
        self.workflow_name = workflow_name
        self.steps = steps
        self.results = []

    def execute(self) -> dict:
        """Execute all workflow steps in sequence."""
        logger.info(f"Starting workflow: {self.workflow_name}")

        for i, step in enumerate(self.steps):
            logger.info(f"Step {i+1}/{len(self.steps)}: {step.name}")

            # Check pre-condition
            if step.pre_condition and not step.pre_condition():
                logger.error(f"Pre-condition failed for step: {step.name}")
                return self._build_result("failed", i)

            # Execute with retries
            success = False
            for attempt in range(step.max_retries + 1):
                try:
                    output = run_ufo_task(step.task, step.timeout)

                    # Validate result
                    if step.post_validation:
                        if not step.post_validation(output):
                            raise ValueError("Post-validation failed")

                    success = True
                    self.results.append({
                        "step": step.name,
                        "status": "completed",
                        "attempt": attempt + 1,
                    })
                    break

                except Exception as e:
                    logger.warning(
                        f"Step '{step.name}' attempt {attempt+1} failed: {e}"
                    )
                    if attempt < step.max_retries:
                        logger.info("Retrying...")
                        time.sleep(3)

            if not success:
                logger.error(f"Step '{step.name}' failed after all retries")
                return self._build_result("failed", i)

        return self._build_result("completed", len(self.steps))

    def _build_result(self, status: str, steps_completed: int) -> dict:
        return {
            "workflow": self.workflow_name,
            "status": status,
            "steps_completed": steps_completed,
            "total_steps": len(self.steps),
            "details": self.results,
        }

Data Transfer Patterns

Cross-application data transfer in UFO relies on three mechanisms:

See AI Voice Agents Handle Real Calls

Book a free demo or calculate how much you can save with AI voice automation.

Clipboard — the primary method. Copy in one app, switch to another, paste. Works for text, images, and formatted content.

File system — save a file from one application, open it in another. Useful for large datasets and binary formats.

Shared text — for small values, include the data directly in the task description: "In Outlook, type the total $1,250,000 in the email body."

FAQ

How does UFO handle timing between application switches?

UFO includes a configurable SLEEP_TIME parameter (default 2 seconds) that pauses between actions to let the UI settle. For cross-application switches, the HostAgent waits for the target window to become active before handing off to the AppAgent. You may need to increase SLEEP_TIME for slower machines or heavy applications.

What happens if data is lost during clipboard transfer between apps?

Clipboard transfer is generally reliable but can fail if another application modifies the clipboard between the copy and paste operations. For critical workflows, verify the paste result by including a verification step: "Verify the pasted data in cell A1 matches the expected header."

Can UFO handle workflows that span more than two applications?

Yes. The HostAgent can coordinate any number of applications in sequence. The orchestrator pattern shown above supports unlimited steps across any number of applications. The primary constraint is the total execution time and API cost.


#CrossAppAutomation #MultiAppWorkflow #DataTransfer #WorkflowOrchestration #MicrosoftUFO #DesktopAutomation #WindowsWorkflows #OfficePipeline

Share this article
C

CallSphere Team

Expert insights on AI voice agents and customer communication automation.

Try CallSphere AI Voice Agents

See how AI voice agents work for your industry. Live demo available -- no signup required.