code: def print_run_plan(run_plan: RunPlan, offers_limit: int = 3):
      job_plan = run_plan.job_plans[0]
  
      props = Table(box=None, show_header=False)
      props.add_column(no_wrap=True)  # key
      props.add_column()  # value
  
      req = job_plan.job_spec.requirements
      pretty_req = req.pretty_format(resources_only=True)
      max_price = f"${req.max_price:g}" if req.max_price else "-"
      max_duration = (
          f"{job_plan.job_spec.max_duration / 3600:g}h"
          if job_plan.job_spec.max_duration
          else "-"
      )
      retry_policy = job_plan.job_spec.retry_policy
      retry_policy = (
          (
              f"{retry_policy.limit / 3600:g}h"
              if retry_policy.limit
              else "yes"
          )
          if retry_policy.retry
          else "no"
      )
  
      if req.spot is None:
          spot_policy = "auto"
      elif req.spot:
          spot_policy = "spot"
      else:
          spot_policy = "on-demand"
  
      def th(s: str) -> str:
          return f"[bold]{s}[/bold]"
  
      props.add_row(
          th("Configuration"), run_plan.run_spec.configuration_path
      )
      props.add_row(th("Project"), run_plan.project_name)
      props.add_row(th("User"), run_plan.user)
      props.add_row(th("Min resources"), pretty_req)
      props.add_row(th("Max price"), max_price)
      props.add_row(th("Max duration"), max_duration)
      props.add_row(th("Spot policy"), spot_policy)
      props.add_row(th("Retry policy"), retry_policy)
  
      offers = Table(box=None)
      offers.add_column("#")
      offers.add_column("BACKEND")
      offers.add_column("REGION")
      offers.add_column("INSTANCE")
      offers.add_column("RESOURCES")
      offers.add_column("SPOT")
      offers.add_column("PRICE")
      offers.add_column()
  
      job_plan.offers = job_plan.offers[:offers_limit]
  
      for i, offer in enumerate(job_plan.offers, start=1):
          r = offer.instance.resources
  
          availability = ""
          if offer.availability in {
              InstanceAvailability.NOT_AVAILABLE,
              InstanceAvailability.NO_QUOTA,
          }:
              availability = offer.availability.value.replace(
                  "_", " "
              ).title()
          offers.add_row(
              f"{i}",
              offer.backend,
              offer.region,
              offer.instance.name,
              r.pretty_format(),
              "yes" if r.spot else "no",
              f"${offer.price:g}",
              availability,
              style=None if i == 1 else "grey58",
          )
      if len(job_plan.offers) == offers_limit:
          offers.add_row("", "...", style="grey58")
  
      console.print(props)
      console.print()
      if len(job_plan.offers) > 0:
          console.print(offers)
          console.print()
  
file_path: dstack/src/dstack/_internal/cli/utils/run.py
imports: from typing import List, Optional
  from rich.table import Table
  from dstack._internal.cli.utils.common import console
  from dstack._internal.core.models.instances import InstanceAvailability, InstanceType, Resources
  from dstack._internal.core.models.runs import RunPlan
  from dstack._internal.utils.common import pretty_date
  from dstack.api import Run
label_desc: Use image node_id 1 for calling a global function with example usage: print_run_plan(run_plan, offers_limit) and returns: str, s, str