Task.run(), run_batch_tasks(), run_batch_task_gen() now take a `max_cost` param, when set to non-zero,
causes task to exit (i.e. done=True) when total token cost across all LLMs exceeds this limit.
This param is passed to the `run` calls to any subtasks as well, so in effect the limit applies across nested tasks.
Note that the task.done() becomes True when the limit is exceeded, and no special treatment is done
to ensure the result returned from the task is reasonable, so it's the responsibility of
the user to handle possibly incomplete or problematic results.