def invoke_action(self, action: ActionDescriptor, args_text: str) -> str:
    r"""Invokes the action on this app instance with the given arguments.

    Args:
      action: The action to invoke.
      args_text: The arguments to pass to the action, each in its own line with
        a colon separating the parameter name from the value, for example:
        'param1: value1\nparam2: value2'

    Returns:
      Textual description of the result of invoking the action.

    Raises:
      ActionArgumentError: If any of the arguments expected by the action are
      missing or if unexpected arguments are provided.
    """
    args = _parse_argument_text(args_text)
    expected_params = {p.name: p for p in action.parameters}

    # Check for missing arguments
    missing_args = set(expected_params) - set(args)
    if missing_args:
      raise ActionArgumentError(
          f"Missing argument(s): {', '.join(missing_args)}"
      )

    # Check for unexpected arguments
    unexpected_args = set(args) - set(expected_params)
    if unexpected_args:
      raise ActionArgumentError(
          f"Unexpected argument(s): {', '.join(unexpected_args)}"
      )

    # Process values
    processed_args = {
        name: expected_params[name].value_from_text(args[name])
        for name in expected_params
    }

    return getattr(self, action.name)(**processed_args)
Invokes the action on this app instance with the given arguments.

    Args:
      action: The action to invoke.
      args_text: The arguments to pass to the action, each in its own line with
        a colon separating the parameter name from the value, for example:
        'param1: value1\nparam2: value2'

    Returns:
      Textual description of the result of invoking the action.

    Raises:
      ActionArgumentError: If any of the arguments expected by the action are
      missing or if unexpected arguments are provided.
    
examples/deprecated/phone/components/apps.py