Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added main entry point #109

Merged
merged 11 commits into from
Oct 22, 2024
Merged

Added main entry point #109

merged 11 commits into from
Oct 22, 2024

Conversation

whitead
Copy link
Contributor

@whitead whitead commented Oct 17, 2024

This is a basic entry point for running agents with an environment for tasks not derived from the task library. Depends on Future-House/aviary#74

pyproject.toml Outdated Show resolved Hide resolved
ldp/alg/callbacks.py Outdated Show resolved Hide resolved
@@ -475,3 +475,53 @@ async def after_eval_loop(self) -> None:
await super().after_eval_loop() # Call the parent to compute means
if self.eval_means:
self._log_filtered_metrics(self.eval_means, step_type="Eval")


class TerminalLoggingCallback(Callback):
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Feel free to ignore for this PR, but we should refactor our logging callback to be general, and move this terminal logging callback to be a composition of the logging callback with a stdout handler or a RichHandler

Our callbacks are a point of tech debt in this framework imo

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Think they do different things though. The one I made is just printing the action actions/observations. The logging callback is a MeanMetricsCallback that logs metrics to logs. Feel like they're pretty different. Maybe we need a guide or something for logging or callbacks :)

from rich.pretty import pprint # noqa: F401
except ImportError:
raise ImportError(
f"rich is required for {type(self).__name__}. Please install it with `pip install rich`."
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should make a rich-specific extra and move our current rich extra to be rich-progress

Or we can leave as is

Comment on lines +512 to +513
print("\nAction:")
pprint(action.value, expand_all=True)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why have 2+ print invocations? Can we make it just one with \n?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These are different - print vs pprint?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah why not just always use pprint?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How would you concat them?

pprint("Action\n", action.value) is not valid and pprint(f"Action\n{str(action.value)}") defeats the purpose of using pprint

and pprint("Action\n") prints the python rep of that string instead of literally printing the words Action followed by a newline.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah I see, you're right. Thanks for going through this with me 👍

except ImportError:
raise ImportError(
f"rich is required for {type(self).__name__}. Please install it with `pip install rich`."
)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why not raise ImportError("...") from exc? Maybe it's me, but I find having the "niceified" error connected to the un-niceified error to be useful

ldp/main.py Outdated
from ldp.alg.rollout import RolloutManager


def agent_factory(agent: Agent | str | PathLike) -> Agent:
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Normally a factory is like a classmethod going from a type to an instance. Can we have this support type[Agent]?

Also, can you add a docstring stating the possible modes checked?

"""
Construct an agent.

Args:
    agent: Either an agent instance, a name for an agent, or a path to an agent pickle.
"""

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is more logically connected to parsing user input - I extracted it out of main - and so I think it's better here where I use it.

I changed the name. Feel like the type hints and name are enough documentation.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What do you think of naming this resolve_agent? Also, feel free to ignore this one

ldp/alg/callbacks.py Show resolved Hide resolved
pyproject.toml Outdated
@@ -317,6 +317,7 @@ ignore = [
"ARG003", # Thrown all the time when we are subclassing
"ASYNC109", # Buggy, SEE: https://github.com/astral-sh/ruff/issues/12353
"ASYNC2", # It's ok to mix async and sync ops (like opening a file)
"B904",
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I like B904 because it makes the code explicit, but I am not that attached to it.

Would you be open to reverting this? I don't think this PR uses it

ldp/main.py Outdated
from ldp.alg.rollout import RolloutManager


def agent_factory(agent: Agent | str | PathLike) -> Agent:
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What do you think of naming this resolve_agent? Also, feel free to ignore this one

Comment on lines +23 to +28
path = Path(agent)
if not path.exists():
raise ValueError(f"Could not resolve agent: {agent}")

with path.open("rb") as f:
return pickle.load(f) # noqa: S301
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
path = Path(agent)
if not path.exists():
raise ValueError(f"Could not resolve agent: {agent}")
with path.open("rb") as f:
return pickle.load(f) # noqa: S301
try:
with path.open("rb") as f:
return pickle.load(f) # noqa: S301
except FileNotFoundError:
raise ValueError(f"Could not resolve agent: {agent}") from None

Alternate way of doing this

Comment on lines +512 to +513
print("\nAction:")
pprint(action.value, expand_all=True)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah I see, you're right. Thanks for going through this with me 👍

@whitead whitead merged commit 17d0408 into main Oct 22, 2024
5 of 6 checks passed
@whitead whitead deleted the main-entry branch October 22, 2024 00:09
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants