settings
¶
Global user settings for mujoco_mojo, persisted to ~/.mujoco-mojo/settings.toml.
VisualizationSettings
¶
Bases: BaseModel
Colors for force, torque, contact, and proximity overlays rendered during simulation.
SensAIModelEntry
¶
Bases: BaseModel
One entry in SensAISettings.models - a provider paired with that provider's own model identifier.
SensAISettings
¶
Bases: BaseModel
Settings for the SensAI assistant embedded in the Dojo dashboard.
-
Code Reference
mujoco_mojoutilslayersdojorouterssensaipost_config
SlurmExtraSettings
¶
GeneralSettings
¶
Bases: BaseModel
General-purpose defaults shared across mujoco-mojo's CLI commands, plus asset-bundling behavior.
MonteCarloRunSettings
¶
Bases: _RunDefaults
Settings for mujoco-mojo run monte-carlo.
SingleRunSettings
¶
Bases: _RunDefaults
Settings for mujoco-mojo run single.
OptimizeRunSettings
¶
Bases: _RunDefaults
Settings for mujoco-mojo run optimization.
GenerateJsonSchemaWithDefaults
¶
Bases: GenerateJsonSchema
Appends each field's default value to its description, so editors that only surface description on hover (e.g. VS Code's Even Better TOML) still show it, without hand-duplicating every Field(default=...) into its own description text.
Also attaches an x-enum-descriptions extension (value -> that member's own attribute-docstring, via _enum_value_descriptions above) to every enum schema - generic to any StrEnum with attribute-docstring'd members, not specific to whichever model happens to use this generator, so a consumer like the Dojo settings panel and PlotConfig's Plot Editor/JSON editor tooltips (dojo/plot_config.py) both get per-dropdown-option descriptions for free from the same one generator, rather than each redefining this behavior in its own subclass.
get_default_value
¶
get_default_value(schema: WithDefaultSchema) -> Any
Pydantic's own default implementation only ever surfaces a static default=, never a default_factory= result, since a factory could be expensive or side-effecting. Every default_factory actually used across this codebase (dict, list, lambda: SlurmExtraSettings({}), and the nested settings-group constructors) is cheap and side-effect-free, so calling it here is safe, and it's what lets _append_defaults below show a real "Default: ..." for fields like PlotConfig.y_axes/annotations/shapes that would otherwise silently show none.
Source code in src/mujoco_mojo/settings.py
MujocoMojoSettings
¶
Bases: BaseSettings
Global user-level settings persisted to ~/.mujoco-mojo/settings.toml, layered with an optional project-local override file - the same User-settings-vs-Workspace-settings model VS Code uses.
Instantiate to load. Sources are checked in priority order: constructor kwargs > environment variables > .env file (env_file in model_config) > project settings file (project_settings_file(), <cwd>/.mujoco-mojo/settings.toml) > global settings file (~/.mujoco-mojo/settings.toml) > defaults. Every field can be overridden at the project level, not just a specific subset - a project file is expected to hold only the handful of keys that genuinely differ from the global defaults (e.g. per-project SLURM extras or force-scaling), not a full copy. Environment variables (real ones and .env entries alike) use the prefix MUJOCO_MOJO_ with __ as the nested delimiter, e.g. MUJOCO_MOJO_DOJO__SENSAI__MODEL_NAME=llama3.2:3b.
-
Code Reference
mujoco_mojosettingsMujocoMojoSettingsdefaults
defaults
classmethod
¶
defaults() -> MujocoMojoSettings
Builds a fresh instance from pure code-level defaults, ignoring environment variables and any existing settings.toml.
A constructor kwarg left unset resolves against this class's other settings sources (env vars, then the TOML file) rather than the field's own default - that layering is the entire reason BaseSettings exists - so every field's default must be passed explicitly here to get a true reset. Iterating model_fields rather than hand-listing field names means a newly added settings field is automatically covered, with nothing to remember to update.
Returns:
| Type | Description |
|---|---|
MujocoMojoSettings
|
A |
Source code in src/mujoco_mojo/settings.py
set_project_value
classmethod
¶
Sets a single dotted-path setting (e.g. "assets.symlink") in the project-local settings file, creating any intermediate tables as needed, without touching anything else already there.
key.split(".") is ambiguous for a free-form group like slurm (a RootModel[dict[str, ...]]), whose own keys legitimately contain literal dots (e.g. "sbatch.account") - "slurm.sbatch.account" must set that one flat key, not descend two more table levels. Resolved by walking the declared field types (not the current data) until a RootModel field is reached; everything after that point is rejoined into a single literal key instead of split further.
Validated by overlaying the new value onto the full currently-effective settings (project + global + env + defaults) and calling model_validate on the result - model_config forbids extra fields on every fixed-shape settings group, so a typo'd leaf and a wrong-typed value both raise pydantic.ValidationError before anything is written. The validated and re-dumped leaf value is what actually gets persisted, not the raw value argument, so e.g. the CLI's loosely-typed input string "true" for a bool field is written to TOML as a real boolean, not a quoted string. Only that one changed leaf is written into the project file, keeping it a small, deliberate diff rather than a full mirror of every setting - contrast with save(), which always persists every field (correct for the global file, wrong here).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
key
|
str
|
Dotted path, e.g. "dojo.sensai.base_url", "assets.symlink", or "slurm.sbatch.account". |
required |
value
|
Any
|
The value to set, already parsed to its target Python type. |
required |
Raises:
| Type | Description |
|---|---|
KeyError
|
If an intermediate segment of |
ValidationError
|
If the resulting settings are invalid (unknown leaf, wrong type, etc.). |
Source code in src/mujoco_mojo/settings.py
| Python | |
|---|---|
1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 | |
save
¶
Persist settings to directory (defaults to the global settings directory, ~/.mujoco-mojo), alongside a freshly (re)generated settings.schema.json/.taplo.toml pair (see write_schema_files) - one method covers both the global settings file and a project-local override file, so there's no separate init_project_file-style method to keep in sync with this one.
project=False (the default - the global file): every field's current value is merged into settings.toml with tomlkit, preserving any comments or formatting added by hand. A key that exists in the file but no longer has a corresponding settings value (e.g. a removed slurm entry) is left as-is rather than deleted.
project=True (for <cwd>/.mujoco-mojo/settings.toml): self's field values are never written - a project file is meant to hold only a small, deliberate diff from the global defaults, not a full mirror of every setting (see set_project_value) - so an existing file's contents are left completely untouched, and a fresh one gets just the #:schema header. Also drops a .gitignore (*) next to it if one isn't already there, so a project's local overrides - which may be machine-specific - don't get committed by accident.
Either way, a brand-new file starts with a #:schema header pointing at the colocated settings.schema.json - a bare relative filename, resolved by taplo against the TOML file's own directory, rather than a cross-directory reference to another directory's schema. The latter is what broke under SSH/SSHFS-style setups where only one of the two directories was visible to the editor - every settings directory is now self-contained. An existing file that's missing that header (written before schema support existed, or hand-edited to drop the line) gets it prepended on the next save too, except for the already-exists project-file case just above, which skips reading the file at all.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
directory
|
Path | None
|
Where to write |
None
|
project
|
bool
|
Write the sparse project-local form described above instead of the full global one. |
False
|
Returns:
| Type | Description |
|---|---|
Path
|
The |
Source code in src/mujoco_mojo/settings.py
write_schema_files
classmethod
¶
write_schema_files(directory: Path | None = None) -> None
Writes settings.schema.json and a companion .taplo.toml into directory, so taplo-based editors (VS Code's Even Better TOML, Neovim, etc.) get hover hints and validation for whatever settings.toml lives there. Safe to re-run any time, e.g. after upgrading mujoco-mojo changes the settings shape.
The schema and taplo config are always colocated with the settings.toml they describe, rather than one directory's file referencing another's schema by absolute path - that cross-directory reference is exactly what broke under SSH/SSHFS-style setups where only one of the two directories (typically just the project one) is visible to the editor.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
directory
|
Path | None
|
Where to write |
None
|
Source code in src/mujoco_mojo/settings.py
project_settings_file
¶
project_settings_file() -> Path
Path to the project-local settings file, <cwd>/.mujoco-mojo/settings.toml.
Computed fresh on every call rather than cached as a module-level constant, since Path.cwd() can legitimately differ across calls within one process (e.g. a long-running dashboard server, or tests).
Returns:
| Type | Description |
|---|---|
Path
|
|