Monty.Runtime.Model (ExTbpMonty.Core v0.1.0)

Copy Markdown View Source

One running Monty model: its modules as supervised processes, and the step coordinator.

The supervision tree is the wiring. Sensor and learning modules are children with restart: :permanent, the coordinator is last, and the strategy is :one_for_one — a module that dies is replaced while the coordinator keeps its step count, because it addresses modules by registered name rather than by pid. The episode's random stream (Monty.Random.Stream) is a child too: it outlives a step and a module, and dies with the model.

start_link/1 takes the model id plus the module specs:

Monty.Runtime.Model.start_link(%{
  model_id: :demo,
  sensor_modules: [%{id: :patch, agent_id: "agent_id_0", module: SomeSM, state: SomeSM.new()}],
  learning_modules: [%{id: :lm_0, module: SomeLM, state: SomeLM.new()}],
  sm_to_lm: %{lm_0: [:patch]},
  motor: {SomeMotor, SomeMotor.new()}
})

Steps are driven from outside (step/4) because the environment owns the clock; a LiveView, an Oban job or a test decides when the next step happens.

Summary

Functions

Returns a specification to start this module under a supervisor.

The modules' own states as they stand, for a logger writing an episode in full.

Whether the model has concluded this episode.

Tells every module which object this episode is about.

Clears short-term memory for a new episode, keeping long-term memory.

Tells the model and its modules whether this episode trains or evaluates.

The coordinator's state, for tests and the run inspector.

The four things a recognition policy may read off the model.

Stops a model started under the application's ModelSupervisor.

Tells the modules the episode's answer, as a supervised experiment knows it.

Switches the model into exploratory mode.

Ends the episode without a conclusion.

Hands what the episode saw to long-term memory.

A :via name for a model's supervisor.

Types

options()

@type options() :: map()

Functions

child_spec(init_arg)

Returns a specification to start this module under a supervisor.

See Supervisor.

detailed(model_id, projection \\ & &1)

@spec detailed(atom() | String.t(), (term() -> term())) ::
  Monty.Runtime.Step.detailed()

The modules' own states as they stand, for a logger writing an episode in full.

Monty's loggers read their modules straight off the model; here the modules are processes, so this is the model being asked for all of them at once. See Monty.Runtime.Step.detailed/2 for why the caller brings a projection.

done?(model_id)

@spec done?(atom() | String.t()) :: boolean()

Whether the model has concluded this episode.

fixme_set_ground_truth(model_id, primary_target, opts \\ [])

@spec fixme_set_ground_truth(atom() | String.t(), map() | nil, keyword()) :: :ok

Tells every module which object this episode is about.

reset_episode(model_id)

@spec reset_episode(atom() | String.t()) :: :ok

Clears short-term memory for a new episode, keeping long-term memory.

set_experiment_mode(model_id, mode)

Tells the model and its modules whether this episode trains or evaluates.

start_link(options)

@spec start_link(options()) :: Supervisor.on_start()

state(model_id)

@spec state(atom() | String.t()) :: Monty.Runtime.Step.State.t()

The coordinator's state, for tests and the run inspector.

status(model_id)

The four things a recognition policy may read off the model.

step(model_id, observations, proprioceptive_state, ctx)

@spec step(atom() | String.t(), map(), map(), Monty.Context.t()) ::
  {:ok, [map()], map()}

Runs one step of a model by id.

A coordinator that dies takes the step with it, and GenServer.call hands the caller an exit whose reason is the exception the step was running. That exit is unwrapped here, so the caller sees the exception the step died of — with the step's own traceback, where the failing module's frame is — rather than "a process exited", which is all a page could say about it otherwise (Monty.Studio.Failure).

Anything else a call can be handed stays an exit: a model that is not running is nobody's exception.

stop(model_id)

@spec stop(atom() | String.t()) :: :ok | {:error, :not_found}

Stops a model started under the application's ModelSupervisor.

A model is stopped by terminating its supervisor; the children go with it, so no module process outlives the run it belonged to.

supervise(model_id, target, location_on_model, supervised_ids)

@spec supervise(atom() | String.t(), map(), [number()], [String.t()]) :: :ok

Tells the modules the episode's answer, as a supervised experiment knows it.

Monty's _pass_target_info_to_model: the modules the experiment names are given the object, its pose and where it stood; every other module's hypotheses are dropped, because what it guessed is not something to learn from.

switch_to_exploratory_step(model_id)

@spec switch_to_exploratory_step(atom() | String.t()) :: :ok

Switches the model into exploratory mode.

time_out(model_id)

@spec time_out(atom() | String.t()) :: :ok

Ends the episode without a conclusion.

update_ltm(model_id)

@spec update_ltm(atom() | String.t()) :: :ok

Hands what the episode saw to long-term memory.

via(model_id)

@spec via(atom() | String.t()) :: {:via, module(), {atom(), term()}}

A :via name for a model's supervisor.