magma-core 2.0.0b1__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- magma_core-2.0.0b1/LICENSE +24 -0
- magma_core-2.0.0b1/PKG-INFO +64 -0
- magma_core-2.0.0b1/README.md +39 -0
- magma_core-2.0.0b1/pyproject.toml +43 -0
- magma_core-2.0.0b1/setup.cfg +4 -0
- magma_core-2.0.0b1/src/magma_core/__init__.py +4 -0
- magma_core-2.0.0b1/src/magma_core/_clients/__init__.py +7 -0
- magma_core-2.0.0b1/src/magma_core/_clients/client_base.py +41 -0
- magma_core-2.0.0b1/src/magma_core/_clients/client_factory.py +22 -0
- magma_core-2.0.0b1/src/magma_core/_clients/ollama_client.py +48 -0
- magma_core-2.0.0b1/src/magma_core/_prompts/__init__.py +2 -0
- magma_core-2.0.0b1/src/magma_core/_prompts/coach/diagnostic/coach_diagnose.py +120 -0
- magma_core-2.0.0b1/src/magma_core/_prompts/coach/diagnostic/diag_non_optimal.py +119 -0
- magma_core-2.0.0b1/src/magma_core/_prompts/coach/diagnostic/select_similar_cases.py +19 -0
- magma_core-2.0.0b1/src/magma_core/_prompts/coach/specific_failure/fix_say_prompt.py +24 -0
- magma_core-2.0.0b1/src/magma_core/_prompts/coach/specific_failure/fix_text_only_answer_prompt.py +58 -0
- magma_core-2.0.0b1/src/magma_core/_prompts/coach/specific_failure/format_prompt.py +36 -0
- magma_core-2.0.0b1/src/magma_core/_prompts/dataset/evaluate_leaf_prompt.py +178 -0
- magma_core-2.0.0b1/src/magma_core/_prompts/dataset/memory_prompt.py +287 -0
- magma_core-2.0.0b1/src/magma_core/_prompts/dataset/paraphrasing.py +140 -0
- magma_core-2.0.0b1/src/magma_core/_prompts/userSim/judge_prompt.py +61 -0
- magma_core-2.0.0b1/src/magma_core/_prompts/userSim/paraphrasing_prompt.py +107 -0
- magma_core-2.0.0b1/src/magma_core/configs/__init__.py +6 -0
- magma_core-2.0.0b1/src/magma_core/configs/config.py +170 -0
- magma_core-2.0.0b1/src/magma_core/configs/default_config.yaml +57 -0
- magma_core-2.0.0b1/src/magma_core/dataset_export.py +80 -0
- magma_core-2.0.0b1/src/magma_core/domain/__init__.py +7 -0
- magma_core-2.0.0b1/src/magma_core/domain/agent_call.py +96 -0
- magma_core-2.0.0b1/src/magma_core/protocol/__init__.py +6 -0
- magma_core-2.0.0b1/src/magma_core/protocol/agent.py +112 -0
- magma_core-2.0.0b1/src/magma_core/protocol/agent_coaching.py +141 -0
- magma_core-2.0.0b1/src/magma_core/protocol/agent_export.py +83 -0
- magma_core-2.0.0b1/src/magma_core/protocol/coaching.py +34 -0
- magma_core-2.0.0b1/src/magma_core/protocol/graph.py +49 -0
- magma_core-2.0.0b1/src/magma_core/protocol/payload/__init__.py +10 -0
- magma_core-2.0.0b1/src/magma_core/protocol/payload/base_payload.py +67 -0
- magma_core-2.0.0b1/src/magma_core/protocol/payload/coaching_common.py +113 -0
- magma_core-2.0.0b1/src/magma_core/protocol/payload/dataset_build_payload.py +138 -0
- magma_core-2.0.0b1/src/magma_core/protocol/payload/diagnosis_payload.py +249 -0
- magma_core-2.0.0b1/src/magma_core/protocol/payload/generic_coaching.py +148 -0
- magma_core-2.0.0b1/src/magma_core/protocol/payload/repr_instruction_variation.py +56 -0
- magma_core-2.0.0b1/src/magma_core/protocol/payload/user_sim_payload.py +102 -0
- magma_core-2.0.0b1/src/magma_core/serialization/__init__.py +24 -0
- magma_core-2.0.0b1/src/magma_core/serialization/spec.py +157 -0
- magma_core-2.0.0b1/src/magma_core/serialization/values.py +118 -0
- magma_core-2.0.0b1/src/magma_core/simulation/__init__.py +1 -0
- magma_core-2.0.0b1/src/magma_core/simulation/agents/__init__.py +10 -0
- magma_core-2.0.0b1/src/magma_core/simulation/agents/answers.py +98 -0
- magma_core-2.0.0b1/src/magma_core/simulation/constraints/__init__.py +1 -0
- magma_core-2.0.0b1/src/magma_core/simulation/constraints/base_constraint.py +46 -0
- magma_core-2.0.0b1/src/magma_core/simulation/data_structures/__init__.py +76 -0
- magma_core-2.0.0b1/src/magma_core/simulation/data_structures/env.py +298 -0
- magma_core-2.0.0b1/src/magma_core/simulation/data_structures/errors.py +3 -0
- magma_core-2.0.0b1/src/magma_core/simulation/data_structures/executor_agent_link.py +131 -0
- magma_core-2.0.0b1/src/magma_core/simulation/data_structures/observation.py +13 -0
- magma_core-2.0.0b1/src/magma_core/simulation/data_structures/situation.py +322 -0
- magma_core-2.0.0b1/src/magma_core/simulation/data_structures/tools.py +335 -0
- magma_core-2.0.0b1/src/magma_core/simulation/envs/__init__.py +7 -0
- magma_core-2.0.0b1/src/magma_core/simulation/envs/default_env.py +289 -0
- magma_core-2.0.0b1/src/magma_core/simulation/envs/default_multi_agent_env.py +23 -0
- magma_core-2.0.0b1/src/magma_core/simulation/errors/__init__.py +3 -0
- magma_core-2.0.0b1/src/magma_core/simulation/errors/base_error.py +92 -0
- magma_core-2.0.0b1/src/magma_core/simulation/executor/__init__.py +7 -0
- magma_core-2.0.0b1/src/magma_core/simulation/executor/executor.py +329 -0
- magma_core-2.0.0b1/src/magma_core/simulation/executor/mono_task_executor.py +209 -0
- magma_core-2.0.0b1/src/magma_core/simulation/goals/__init__.py +17 -0
- magma_core-2.0.0b1/src/magma_core/simulation/goals/base_goal.py +188 -0
- magma_core-2.0.0b1/src/magma_core/simulation/goals/failure.py +101 -0
- magma_core-2.0.0b1/src/magma_core/simulation/goals/positive.py +141 -0
- magma_core-2.0.0b1/src/magma_core/simulation/randomizer/__init__.py +4 -0
- magma_core-2.0.0b1/src/magma_core/simulation/randomizer/base_random_wrapper.py +101 -0
- magma_core-2.0.0b1/src/magma_core/simulation/randomizer/random_spec.py +37 -0
- magma_core-2.0.0b1/src/magma_core/simulation/randomizer/runtime_randomizer.py +488 -0
- magma_core-2.0.0b1/src/magma_core/simulation/randomizer/spec_generator.py +531 -0
- magma_core-2.0.0b1/src/magma_core/simulation/requests/__init__.py +3 -0
- magma_core-2.0.0b1/src/magma_core/simulation/requests/base_request.py +39 -0
- magma_core-2.0.0b1/src/magma_core/simulation/serialization/__init__.py +24 -0
- magma_core-2.0.0b1/src/magma_core/simulation/serialization/values.py +55 -0
- magma_core-2.0.0b1/src/magma_core/simulation/skills/__init__.py +38 -0
- magma_core-2.0.0b1/src/magma_core/simulation/skills/adapter.py +55 -0
- magma_core-2.0.0b1/src/magma_core/simulation/skills/skill.py +149 -0
- magma_core-2.0.0b1/src/magma_core/simulation/skills/skill_manager.py +654 -0
- magma_core-2.0.0b1/src/magma_core/simulation/skills/structure.py +591 -0
- magma_core-2.0.0b1/src/magma_core/simulation/stage/__init__.py +33 -0
- magma_core-2.0.0b1/src/magma_core/simulation/stage/base_stage.py +482 -0
- magma_core-2.0.0b1/src/magma_core/simulation/stage/environment_transition.py +35 -0
- magma_core-2.0.0b1/src/magma_core/simulation/stage/stage_composite.py +161 -0
- magma_core-2.0.0b1/src/magma_core/simulation/stage/stage_template.py +209 -0
- magma_core-2.0.0b1/src/magma_core/simulation/state/__init__.py +9 -0
- magma_core-2.0.0b1/src/magma_core/simulation/state/task_state.py +122 -0
- magma_core-2.0.0b1/src/magma_core/simulation/tasks/__init__.py +8 -0
- magma_core-2.0.0b1/src/magma_core/simulation/tasks/base_task.py +652 -0
- magma_core-2.0.0b1/src/magma_core/simulation/tasks/benchmark_task.py +133 -0
- magma_core-2.0.0b1/src/magma_core/simulation/tasks/definition.py +99 -0
- magma_core-2.0.0b1/src/magma_core/simulation/tasks_style.py +25 -0
- magma_core-2.0.0b1/src/magma_core/simulation/tools/__init__.py +7 -0
- magma_core-2.0.0b1/src/magma_core/simulation/tools/base_tool.py +183 -0
- magma_core-2.0.0b1/src/magma_core/simulation/tools/decorator.py +105 -0
- magma_core-2.0.0b1/src/magma_core/simulation/trajectory/__init__.py +6 -0
- magma_core-2.0.0b1/src/magma_core/simulation/trajectory/action_converter.py +289 -0
- magma_core-2.0.0b1/src/magma_core/simulation/utils/__init__.py +1 -0
- magma_core-2.0.0b1/src/magma_core/simulation/utils/env_utils.py +37 -0
- magma_core-2.0.0b1/src/magma_core/simulation/utils/gripper_utils.py +72 -0
- magma_core-2.0.0b1/src/magma_core/utils/__init__.py +4 -0
- magma_core-2.0.0b1/src/magma_core/utils/data_utils.py +81 -0
- magma_core-2.0.0b1/src/magma_core/utils/global_utils.py +240 -0
- magma_core-2.0.0b1/src/magma_core/utils/text_utils.py +192 -0
- magma_core-2.0.0b1/src/magma_core/workers/__init__.py +20 -0
- magma_core-2.0.0b1/src/magma_core/workers/base.py +13 -0
- magma_core-2.0.0b1/src/magma_core/workers/coaching_logs.py +25 -0
- magma_core-2.0.0b1/src/magma_core/workers/coaching_sessions.py +167 -0
- magma_core-2.0.0b1/src/magma_core/workers/human_coaching.py +143 -0
- magma_core-2.0.0b1/src/magma_core/workers/pool.py +105 -0
- magma_core-2.0.0b1/src/magma_core/workers/worker.py +293 -0
- magma_core-2.0.0b1/src/magma_core.egg-info/PKG-INFO +64 -0
- magma_core-2.0.0b1/src/magma_core.egg-info/SOURCES.txt +131 -0
- magma_core-2.0.0b1/src/magma_core.egg-info/dependency_links.txt +1 -0
- magma_core-2.0.0b1/src/magma_core.egg-info/requires.txt +20 -0
- magma_core-2.0.0b1/src/magma_core.egg-info/top_level.txt +1 -0
- magma_core-2.0.0b1/tests/test_base_error.py +34 -0
- magma_core-2.0.0b1/tests/test_base_request.py +57 -0
- magma_core-2.0.0b1/tests/test_base_task.py +511 -0
- magma_core-2.0.0b1/tests/test_config.py +158 -0
- magma_core-2.0.0b1/tests/test_data_utils.py +70 -0
- magma_core-2.0.0b1/tests/test_env_and_gripper_utils.py +99 -0
- magma_core-2.0.0b1/tests/test_goals.py +105 -0
- magma_core-2.0.0b1/tests/test_runtime_randomizer.py +451 -0
- magma_core-2.0.0b1/tests/test_stage_env_completion.py +82 -0
- magma_core-2.0.0b1/tests/test_stage_template.py +37 -0
- magma_core-2.0.0b1/tests/test_task_state.py +83 -0
- magma_core-2.0.0b1/tests/test_text_utils.py +69 -0
- magma_core-2.0.0b1/tests/test_tool_error_flags.py +707 -0
- magma_core-2.0.0b1/tests/test_worker_pool.py +310 -0
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
BSD 2-Clause License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026, MAGMA-s
|
|
4
|
+
|
|
5
|
+
Redistribution and use in source and binary forms, with or without
|
|
6
|
+
modification, are permitted provided that the following conditions are met:
|
|
7
|
+
|
|
8
|
+
1. Redistributions of source code must retain the above copyright notice, this
|
|
9
|
+
list of conditions and the following disclaimer.
|
|
10
|
+
|
|
11
|
+
2. Redistributions in binary form must reproduce the above copyright notice,
|
|
12
|
+
this list of conditions and the following disclaimer in the documentation
|
|
13
|
+
and/or other materials provided with the distribution.
|
|
14
|
+
|
|
15
|
+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
|
16
|
+
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
17
|
+
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
|
18
|
+
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
|
19
|
+
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
|
20
|
+
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
|
21
|
+
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
|
22
|
+
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
|
23
|
+
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
24
|
+
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: magma_core
|
|
3
|
+
Version: 2.0.0b1
|
|
4
|
+
Summary: Core abstractions and protocols for MAGMA
|
|
5
|
+
Requires-Python: <3.13,>=3.12
|
|
6
|
+
Description-Content-Type: text/markdown
|
|
7
|
+
License-File: LICENSE
|
|
8
|
+
Requires-Dist: torch==2.13.0
|
|
9
|
+
Requires-Dist: requests<3,>=2.34.2
|
|
10
|
+
Requires-Dist: PyYAML<7,>=6.0.3
|
|
11
|
+
Requires-Dist: pydantic<3,>=2.4
|
|
12
|
+
Requires-Dist: typing_extensions>=4.0
|
|
13
|
+
Provides-Extra: interface
|
|
14
|
+
Provides-Extra: simulation
|
|
15
|
+
Requires-Dist: mani_skill==3.0.1; extra == "simulation"
|
|
16
|
+
Requires-Dist: sapien==3.0.3; extra == "simulation"
|
|
17
|
+
Requires-Dist: numpy==1.26.4; extra == "simulation"
|
|
18
|
+
Requires-Dist: gymnasium==1.3.0; extra == "simulation"
|
|
19
|
+
Requires-Dist: transforms3d==0.4.2; extra == "simulation"
|
|
20
|
+
Provides-Extra: all
|
|
21
|
+
Requires-Dist: magma_core[simulation]; extra == "all"
|
|
22
|
+
Provides-Extra: dev
|
|
23
|
+
Requires-Dist: pytest; extra == "dev"
|
|
24
|
+
Dynamic: license-file
|
|
25
|
+
|
|
26
|
+
# magma-core
|
|
27
|
+
MAGMA core is one Python package with two dependency zones. Version 2.0.0b1
|
|
28
|
+
is the first beta of v2. This beta supports Python 3.12; simulation installation
|
|
29
|
+
was checked on Linux x86_64. Broader Python/platform support is not yet validated.
|
|
30
|
+
|
|
31
|
+
## Description
|
|
32
|
+
|
|
33
|
+
magma_core contains protocol, base classes and utils used by different magma packages.
|
|
34
|
+
|
|
35
|
+
## Installation
|
|
36
|
+
|
|
37
|
+
### Pip
|
|
38
|
+
|
|
39
|
+
```bash
|
|
40
|
+
pip install "magma_core==2.0.0b1" # Simulator-independent interface
|
|
41
|
+
pip install "magma_core[interface]==2.0.0b1" # Alias for the default install
|
|
42
|
+
pip install "magma_core[simulation]==2.0.0b1" # Includes simulation dependencies
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
For a local checkout, use `pip install -e .` or `pip install -e ".[all]"`.
|
|
46
|
+
Extras add dependencies; they do not change which Python modules are shipped.
|
|
47
|
+
The default installation includes Torch, requests, PyYAML, Pydantic, and
|
|
48
|
+
`typing_extensions`, but does not require ManiSkill, SAPIEN, or Gymnasium.
|
|
49
|
+
|
|
50
|
+
### Github
|
|
51
|
+
|
|
52
|
+
```bash
|
|
53
|
+
pip install "git+https://github.com/MAGMA-rob/magma-core.git@main"
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
Install a pinned release tag:
|
|
57
|
+
|
|
58
|
+
```bash
|
|
59
|
+
pip install "magma_core[simulation] @ git+https://github.com/MAGMA-rob/magma-core.git@v2.0.0b1"
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
---
|
|
63
|
+
|
|
64
|
+
If you spot any documentation errors, problem in the code. Please contact me at `l.bernat@sileane.com`
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
# magma-core
|
|
2
|
+
MAGMA core is one Python package with two dependency zones. Version 2.0.0b1
|
|
3
|
+
is the first beta of v2. This beta supports Python 3.12; simulation installation
|
|
4
|
+
was checked on Linux x86_64. Broader Python/platform support is not yet validated.
|
|
5
|
+
|
|
6
|
+
## Description
|
|
7
|
+
|
|
8
|
+
magma_core contains protocol, base classes and utils used by different magma packages.
|
|
9
|
+
|
|
10
|
+
## Installation
|
|
11
|
+
|
|
12
|
+
### Pip
|
|
13
|
+
|
|
14
|
+
```bash
|
|
15
|
+
pip install "magma_core==2.0.0b1" # Simulator-independent interface
|
|
16
|
+
pip install "magma_core[interface]==2.0.0b1" # Alias for the default install
|
|
17
|
+
pip install "magma_core[simulation]==2.0.0b1" # Includes simulation dependencies
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
For a local checkout, use `pip install -e .` or `pip install -e ".[all]"`.
|
|
21
|
+
Extras add dependencies; they do not change which Python modules are shipped.
|
|
22
|
+
The default installation includes Torch, requests, PyYAML, Pydantic, and
|
|
23
|
+
`typing_extensions`, but does not require ManiSkill, SAPIEN, or Gymnasium.
|
|
24
|
+
|
|
25
|
+
### Github
|
|
26
|
+
|
|
27
|
+
```bash
|
|
28
|
+
pip install "git+https://github.com/MAGMA-rob/magma-core.git@main"
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
Install a pinned release tag:
|
|
32
|
+
|
|
33
|
+
```bash
|
|
34
|
+
pip install "magma_core[simulation] @ git+https://github.com/MAGMA-rob/magma-core.git@v2.0.0b1"
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
---
|
|
38
|
+
|
|
39
|
+
If you spot any documentation errors, problem in the code. Please contact me at `l.bernat@sileane.com`
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
# SPDX-License-Identifier: BSD-2-Clause
|
|
2
|
+
# Copyright (c) 2026, Loan Bernat
|
|
3
|
+
|
|
4
|
+
[project]
|
|
5
|
+
name = "magma_core"
|
|
6
|
+
version = "2.0.0b1"
|
|
7
|
+
description = "Core abstractions and protocols for MAGMA"
|
|
8
|
+
readme = "README.md"
|
|
9
|
+
# First beta supports the Python minor version used for installation validation.
|
|
10
|
+
requires-python = ">=3.12,<3.13"
|
|
11
|
+
dependencies = [
|
|
12
|
+
"torch==2.13.0",
|
|
13
|
+
"requests>=2.34.2,<3",
|
|
14
|
+
"PyYAML>=6.0.3,<7",
|
|
15
|
+
"pydantic>=2.4,<3",
|
|
16
|
+
"typing_extensions>=4.0",
|
|
17
|
+
]
|
|
18
|
+
|
|
19
|
+
[project.optional-dependencies]
|
|
20
|
+
interface = []
|
|
21
|
+
simulation = [
|
|
22
|
+
"mani_skill==3.0.1",
|
|
23
|
+
"sapien==3.0.3",
|
|
24
|
+
"numpy==1.26.4",
|
|
25
|
+
"gymnasium==1.3.0",
|
|
26
|
+
"transforms3d==0.4.2",
|
|
27
|
+
]
|
|
28
|
+
all = ["magma_core[simulation]"]
|
|
29
|
+
dev = ["pytest"]
|
|
30
|
+
|
|
31
|
+
[build-system]
|
|
32
|
+
requires = ["setuptools>=61.0"]
|
|
33
|
+
build-backend = "setuptools.build_meta"
|
|
34
|
+
|
|
35
|
+
[tool.setuptools.packages.find]
|
|
36
|
+
where = ["src"]
|
|
37
|
+
|
|
38
|
+
[tool.setuptools.package-data]
|
|
39
|
+
"magma_core.configs" = ["*.yaml"]
|
|
40
|
+
|
|
41
|
+
[tool.pytest.ini_options]
|
|
42
|
+
addopts = "-p no:launch_testing -p no:launch_ros"
|
|
43
|
+
testpaths = ["tests"]
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
# SPDX-License-Identifier: BSD-2-Clause
|
|
2
|
+
# Copyright (c) 2026, Loan Bernat
|
|
3
|
+
|
|
4
|
+
from abc import ABC, abstractmethod
|
|
5
|
+
from typing import List, Dict, Any, Optional
|
|
6
|
+
|
|
7
|
+
from magma_core.configs import BackendConfig
|
|
8
|
+
|
|
9
|
+
class LLMClientBase(ABC):
|
|
10
|
+
"""
|
|
11
|
+
Base class to create a custom LLM CLient to handle payload sended by the workers for coaching, user simulation, curriculum etc...
|
|
12
|
+
"""
|
|
13
|
+
|
|
14
|
+
def __init__(self, config: BackendConfig):
|
|
15
|
+
self.config = config
|
|
16
|
+
|
|
17
|
+
@abstractmethod
|
|
18
|
+
def send_prompt(
|
|
19
|
+
self,
|
|
20
|
+
model: Optional[str],
|
|
21
|
+
prompt: str,
|
|
22
|
+
max_tokens: int
|
|
23
|
+
) -> str:
|
|
24
|
+
...
|
|
25
|
+
|
|
26
|
+
@abstractmethod
|
|
27
|
+
def send_messages(
|
|
28
|
+
self,
|
|
29
|
+
model: Optional[str],
|
|
30
|
+
messages: List[Dict[str, Any]],
|
|
31
|
+
max_tokens: int,
|
|
32
|
+
keep_messages: bool = False
|
|
33
|
+
) -> Any:
|
|
34
|
+
...
|
|
35
|
+
|
|
36
|
+
def test_server(self):
|
|
37
|
+
self.send_prompt(
|
|
38
|
+
self.config.default_model,
|
|
39
|
+
"Hello how are you?",
|
|
40
|
+
max_tokens=50
|
|
41
|
+
)
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
# SPDX-License-Identifier: BSD-2-Clause
|
|
2
|
+
# Copyright (c) 2026, Loan Bernat
|
|
3
|
+
|
|
4
|
+
from typing import Type
|
|
5
|
+
from .client_base import LLMClientBase
|
|
6
|
+
from .ollama_client import OllamaClient
|
|
7
|
+
|
|
8
|
+
from magma_core.configs.config import BackendConfig
|
|
9
|
+
|
|
10
|
+
CLIENT_REGISTRY: dict[str, Type[LLMClientBase]] = {
|
|
11
|
+
"ollama" : OllamaClient
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
class ClientFactory:
|
|
15
|
+
|
|
16
|
+
@staticmethod
|
|
17
|
+
def create_client(backend_config : BackendConfig):
|
|
18
|
+
if backend_config.type not in CLIENT_REGISTRY:
|
|
19
|
+
raise ValueError(f"Unknown LM Backend {backend_config.type}. Avalaible are : {','.join(CLIENT_REGISTRY.keys())}")
|
|
20
|
+
|
|
21
|
+
ClientCLS = CLIENT_REGISTRY[backend_config.type]
|
|
22
|
+
return ClientCLS(backend_config)
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
# SPDX-License-Identifier: BSD-2-Clause
|
|
2
|
+
# Copyright (c) 2026, Loan Bernat
|
|
3
|
+
|
|
4
|
+
import requests
|
|
5
|
+
import json
|
|
6
|
+
|
|
7
|
+
from .client_base import LLMClientBase
|
|
8
|
+
|
|
9
|
+
class OllamaClient(LLMClientBase):
|
|
10
|
+
"""
|
|
11
|
+
Client for a Ollama Server
|
|
12
|
+
"""
|
|
13
|
+
|
|
14
|
+
def _send(self, data, url, keep_messages=False):
|
|
15
|
+
for _ in range(self.config.max_retry):
|
|
16
|
+
try:
|
|
17
|
+
r = requests.post(
|
|
18
|
+
url,
|
|
19
|
+
headers=self.config.headers,
|
|
20
|
+
data=json.dumps(data),
|
|
21
|
+
timeout=self.config.timeout
|
|
22
|
+
)
|
|
23
|
+
msg = r.json()["choices"][0]["message"]
|
|
24
|
+
return msg if keep_messages else msg["content"]
|
|
25
|
+
except Exception as e:
|
|
26
|
+
print("Error when posting request to Ollama: " + str(e))
|
|
27
|
+
continue
|
|
28
|
+
raise RuntimeError("Ollama unreachable")
|
|
29
|
+
|
|
30
|
+
def send_prompt(self, model, prompt, max_tokens):
|
|
31
|
+
data = {
|
|
32
|
+
"model": model if model is not None else self.config.default_model,
|
|
33
|
+
"messages": [{"role": "user", "content": prompt}],
|
|
34
|
+
"max_tokens": max_tokens
|
|
35
|
+
}
|
|
36
|
+
return self._send(data, self.config.endpoint)
|
|
37
|
+
|
|
38
|
+
def send_messages(self, model, messages, max_tokens, keep_messages=False):
|
|
39
|
+
data = {
|
|
40
|
+
"model": model if model is not None else self.config.default_model,
|
|
41
|
+
"messages": messages,
|
|
42
|
+
"max_tokens": max_tokens
|
|
43
|
+
}
|
|
44
|
+
return self._send(
|
|
45
|
+
data,
|
|
46
|
+
self.config.endpoint,
|
|
47
|
+
keep_messages
|
|
48
|
+
)
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
COACH_DIAGNOSIS="""
|
|
2
|
+
You are a privileged trajectory coach.
|
|
3
|
+
|
|
4
|
+
You analyze a FAILED execution after the episode has finished.
|
|
5
|
+
|
|
6
|
+
Your task is to identify the EARLIEST decision responsible for preventing the completion of the current Stage Goal.
|
|
7
|
+
|
|
8
|
+
You are NOT asked to repair the trajectory.
|
|
9
|
+
|
|
10
|
+
--------------------------------------------------
|
|
11
|
+
CORE PRINCIPLE
|
|
12
|
+
--------------------------------------------------
|
|
13
|
+
|
|
14
|
+
Identify the EARLIEST SEMANTIC DECISION ERROR in the trajectory.
|
|
15
|
+
|
|
16
|
+
A semantic decision error is the earliest action that deviates from a valid
|
|
17
|
+
progress-making strategy for the Stage Goal, given the privileged task state
|
|
18
|
+
and constraints.
|
|
19
|
+
|
|
20
|
+
IMPORTANT:
|
|
21
|
+
- Execution success does NOT imply that a decision was correct.
|
|
22
|
+
- A successful action can still be the root error if it selects the wrong
|
|
23
|
+
object, wrong robot, wrong ordering, or violates a prerequisite required
|
|
24
|
+
by a later operation.
|
|
25
|
+
- Do NOT select the first bad_call merely because it is where the problem
|
|
26
|
+
became observable.
|
|
27
|
+
- A later invalid action may be only a consequence of an earlier incorrect
|
|
28
|
+
commitment.
|
|
29
|
+
|
|
30
|
+
A decision should be selected if its effect must later be undone, corrected,
|
|
31
|
+
or recovered from before a valid completion of the Stage Goal can continue.
|
|
32
|
+
|
|
33
|
+
COUNTERFACTUAL TEST:
|
|
34
|
+
For candidate decision k:
|
|
35
|
+
1. Keep all decisions BEFORE k unchanged.
|
|
36
|
+
2. Replace decision k with a correct alternative.
|
|
37
|
+
3. Decisions AFTER k are NOT fixed: they may be replanned and re-executed
|
|
38
|
+
from the corrected resulting state.
|
|
39
|
+
4. If this restores a valid progress-making continuation, k is a valid
|
|
40
|
+
candidate.
|
|
41
|
+
5. Among valid candidates, select the earliest one.
|
|
42
|
+
|
|
43
|
+
--------------------------------------------------
|
|
44
|
+
EXECUTION FAILURES
|
|
45
|
+
--------------------------------------------------
|
|
46
|
+
|
|
47
|
+
Execution failures and decision errors are different. A correct decision may fail because of stochastic execution.
|
|
48
|
+
|
|
49
|
+
Never select a decision ONLY because its execution failed. Instead, evaluate whether the subsequent recovery decisions remained consistent with achieving the Stage Goal.
|
|
50
|
+
|
|
51
|
+
If decision X failed due to a 'Stochastic Failure' it will be flagged with 'injection error', that's means that this step can not be the error excepts if the action is not giving any progress toward the goals. Most of the time, the faulty step will be the very next decision because it does not retry.
|
|
52
|
+
|
|
53
|
+
--------------------------------------------------
|
|
54
|
+
SPECIFIC FAILURE INFORMATION
|
|
55
|
+
--------------------------------------------------
|
|
56
|
+
|
|
57
|
+
{specific_failure_paragraph}
|
|
58
|
+
|
|
59
|
+
--------------------------------------------------
|
|
60
|
+
TASK-SPECIFIC COACHING GUIDANCE
|
|
61
|
+
--------------------------------------------------
|
|
62
|
+
|
|
63
|
+
{task_coaching_hint}
|
|
64
|
+
|
|
65
|
+
{validated_similar_cases}
|
|
66
|
+
|
|
67
|
+
--------------------------------------------------
|
|
68
|
+
TASK
|
|
69
|
+
--------------------------------------------------
|
|
70
|
+
|
|
71
|
+
{stage_goal}
|
|
72
|
+
|
|
73
|
+
--------------------------------------------------
|
|
74
|
+
TRAJECTORY
|
|
75
|
+
--------------------------------------------------
|
|
76
|
+
|
|
77
|
+
Decisions with index 0 belong to the validated trajectory prefix. They MUST be considered correct and CANNOT be selected.
|
|
78
|
+
|
|
79
|
+
{trajectory}
|
|
80
|
+
END OF TRAJECTORY
|
|
81
|
+
|
|
82
|
+
--------------------------------------------------
|
|
83
|
+
OUTPUT
|
|
84
|
+
--------------------------------------------------
|
|
85
|
+
|
|
86
|
+
Return exactly one JSON object and nothing else.
|
|
87
|
+
Do not use Markdown.
|
|
88
|
+
Do not wrap the JSON in a code fence.
|
|
89
|
+
The first output character must be {{ and the last output character must be }}.
|
|
90
|
+
The decision_index must be a strictly positive integer corresponding to a
|
|
91
|
+
selectable decision in the trajectory. Never return 0 or a negative index.
|
|
92
|
+
|
|
93
|
+
{{
|
|
94
|
+
"decision_index": <integer>,
|
|
95
|
+
"reason": "<why this is the earliest causal decision>",
|
|
96
|
+
"expected_decision": "<what should have happened instead>"
|
|
97
|
+
}}
|
|
98
|
+
"""
|
|
99
|
+
|
|
100
|
+
FAILURE_PARAGRAPHE = {
|
|
101
|
+
"failure" : """
|
|
102
|
+
The trajectory terminated after an invalid or repetitive action.
|
|
103
|
+
|
|
104
|
+
This termination signal indicates WHERE the failure became visible, not
|
|
105
|
+
necessarily WHERE the policy first made an incorrect decision.
|
|
106
|
+
|
|
107
|
+
Trace backward to the earliest semantic decision error that placed the
|
|
108
|
+
trajectory on this incorrect branch.
|
|
109
|
+
""",
|
|
110
|
+
"no_action": """
|
|
111
|
+
The execution terminated before completing the current Stage Goal because the final action do not contains any tools.
|
|
112
|
+
That implies that the model drift during the trajectory.
|
|
113
|
+
If the model encountered multiple stochastic error, be sure to have try all possible options (objects,zone) that can be used.
|
|
114
|
+
""",
|
|
115
|
+
"exceeded": """
|
|
116
|
+
The episode exceeded the maximum number of decisions before completing the Stage Goal.
|
|
117
|
+
Look for ineffective recovery behaviour, unnecessary repetitions, or missed opportunities that prevented completion.
|
|
118
|
+
Do not simply select the last repeated decision unless it is the first decision that made completion impossible.
|
|
119
|
+
"""
|
|
120
|
+
}
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
# SPDX-License-Identifier: BSD-2-Clause
|
|
2
|
+
# Copyright (c) 2026, Loan Bernat
|
|
3
|
+
|
|
4
|
+
DIAGNOSIS_SUB_OPTI = """\
|
|
5
|
+
You are a privileged trajectory coach analyzing a SUCCESSFUL agent trajectory.
|
|
6
|
+
|
|
7
|
+
The trajectory completed the Stage Goal but required more steps than the expected target.
|
|
8
|
+
This does NOT necessarily mean that it is suboptimal: additional steps may be justified by stochastic execution, partial observations, ambiguous feedback, or necessary recovery.
|
|
9
|
+
|
|
10
|
+
Your task is to determine whether there is a clear local opportunity to complete the SAME Stage Goal with fewer decisions.
|
|
11
|
+
|
|
12
|
+
If yes, identify the EARLIEST decision that should be modified.
|
|
13
|
+
|
|
14
|
+
--------------------------------------------------
|
|
15
|
+
CORE RULE
|
|
16
|
+
--------------------------------------------------
|
|
17
|
+
|
|
18
|
+
A decision at index k is a valid candidate if, while keeping ALL previous
|
|
19
|
+
decisions fixed, replacing that decision could plausibly:
|
|
20
|
+
|
|
21
|
+
1. still complete the Stage Goal;
|
|
22
|
+
2. avoid one or more later decisions;
|
|
23
|
+
3. reduce the total number of decisions.
|
|
24
|
+
|
|
25
|
+
Select the EARLIEST such decision.
|
|
26
|
+
|
|
27
|
+
Do NOT propose the replacement action.
|
|
28
|
+
|
|
29
|
+
--------------------------------------------------
|
|
30
|
+
CAUSALITY AND INFORMATION
|
|
31
|
+
--------------------------------------------------
|
|
32
|
+
|
|
33
|
+
Each step contains:
|
|
34
|
+
|
|
35
|
+
INPUT:
|
|
36
|
+
information available before the decision.
|
|
37
|
+
|
|
38
|
+
TOOL:
|
|
39
|
+
decision made by the agent.
|
|
40
|
+
|
|
41
|
+
RESULT:
|
|
42
|
+
Flag of the error types
|
|
43
|
+
|
|
44
|
+
Judge whether a decision was reasonable using only information available
|
|
45
|
+
in its INPUT and previous trajectory.
|
|
46
|
+
|
|
47
|
+
You may use later steps to understand the consequences of an earlier
|
|
48
|
+
decision, but do NOT use information that was unavailable to the agent
|
|
49
|
+
to claim that an earlier decision was suboptimal.
|
|
50
|
+
|
|
51
|
+
EXECUTION STOCHASTICITY
|
|
52
|
+
|
|
53
|
+
A correct decision may lead to additional steps because execution failed
|
|
54
|
+
or feedback was uncertain. IN this case it will be marked by injection_error.
|
|
55
|
+
|
|
56
|
+
Do NOT mark as suboptimal:
|
|
57
|
+
- justified retries after stochastic failures;
|
|
58
|
+
- observations needed to resolve uncertain or incomplete feedback;
|
|
59
|
+
- necessary exploration;
|
|
60
|
+
- appropriate recovery after execution failure;
|
|
61
|
+
- correct partial progress.
|
|
62
|
+
|
|
63
|
+
A decision MAY be suboptimal if it:
|
|
64
|
+
- performs an unnecessary observation or action;
|
|
65
|
+
- makes a choice that must later be unnecessarily reversed or corrected;
|
|
66
|
+
- ignores already available information;
|
|
67
|
+
- is a bad call;
|
|
68
|
+
- violates a known prerequisite and forces later recovery;
|
|
69
|
+
- creates avoidable additional work.
|
|
70
|
+
|
|
71
|
+
Do not assume that a suboptimal decision exists.
|
|
72
|
+
If no specific local decision can be defensibly identified, answer false.
|
|
73
|
+
|
|
74
|
+
All decisions with index 0 belong to a validated prefix.
|
|
75
|
+
They are correct and CANNOT be selected.
|
|
76
|
+
Only positive indices can be selected.
|
|
77
|
+
|
|
78
|
+
--------------------------------------------------
|
|
79
|
+
ROBOT CONSTRAINTS
|
|
80
|
+
--------------------------------------------------
|
|
81
|
+
|
|
82
|
+
- Only one tool call per robot can be selected at each step.
|
|
83
|
+
- Unless explicitly specified otherwise, a robot can hold only one object.
|
|
84
|
+
- Do not invent task constraints or robot capabilities.
|
|
85
|
+
|
|
86
|
+
TASK:
|
|
87
|
+
{task_description}
|
|
88
|
+
|
|
89
|
+
STAGE GOAL:
|
|
90
|
+
{stage_goal}
|
|
91
|
+
|
|
92
|
+
PERMANENT RULES:
|
|
93
|
+
{permanent_rules}
|
|
94
|
+
|
|
95
|
+
|
|
96
|
+
--------------------------------------------------
|
|
97
|
+
REFERENCE EFFICIENT TRAJECTORY:
|
|
98
|
+
--------------------------------------------------
|
|
99
|
+
|
|
100
|
+
{example_trajectory}
|
|
101
|
+
|
|
102
|
+
This trajectory is only a reference. Execution, objects, positions and
|
|
103
|
+
objectives may differ. Do not transfer assumptions from it.
|
|
104
|
+
|
|
105
|
+
--------------------------------------------------
|
|
106
|
+
TRAJECTORY TO ANALYZE:
|
|
107
|
+
--------------------------------------------------
|
|
108
|
+
|
|
109
|
+
{trajectory}
|
|
110
|
+
|
|
111
|
+
OUTPUT:
|
|
112
|
+
Return only:
|
|
113
|
+
|
|
114
|
+
{{
|
|
115
|
+
"suboptimal": true/false,
|
|
116
|
+
"decision_idx": <positive integer or null>,
|
|
117
|
+
"reason": "<concise explanation>"
|
|
118
|
+
}}
|
|
119
|
+
"""
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
# SPDX-License-Identifier: BSD-2-Clause
|
|
2
|
+
# Copyright (c) 2026, Loan Bernat
|
|
3
|
+
|
|
4
|
+
SELECT_SIMILAR_CASES = """
|
|
5
|
+
Select the stored cases that are genuinely useful for diagnosing the current
|
|
6
|
+
failed trajectory.
|
|
7
|
+
|
|
8
|
+
CURRENT STAGE GOAL
|
|
9
|
+
{stage_goal}
|
|
10
|
+
|
|
11
|
+
CURRENT TRAJECTORY
|
|
12
|
+
{trajectory}
|
|
13
|
+
|
|
14
|
+
STORED CASES
|
|
15
|
+
{cases}
|
|
16
|
+
|
|
17
|
+
Return only a JSON array containing the useful case numbers, for example
|
|
18
|
+
[1, 3]. Return [] when none is useful. Do not return Markdown or explanations.
|
|
19
|
+
"""
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
FIX_TEXT_ONLY = """
|
|
2
|
+
You are rewriting a rejected text-only robot answer.
|
|
3
|
+
|
|
4
|
+
The corrected answer must be a plain natural-language message to the user.
|
|
5
|
+
No tool call is possible for this correction.
|
|
6
|
+
|
|
7
|
+
Stage goal:
|
|
8
|
+
{stage_goal}
|
|
9
|
+
|
|
10
|
+
Rejected answer:
|
|
11
|
+
{rejected_answer}
|
|
12
|
+
|
|
13
|
+
Rejection reason:
|
|
14
|
+
{rejection_reason}
|
|
15
|
+
|
|
16
|
+
Rules:
|
|
17
|
+
- Return only the corrected message string.
|
|
18
|
+
- Do not return JSON.
|
|
19
|
+
- Do not add markdown fences or labels.
|
|
20
|
+
- Do not mention the rejection reason.
|
|
21
|
+
- Do not mention validation, formatting, or internal checks.
|
|
22
|
+
- Keep any useful content from the rejected answer when it is compatible with the stage goal.
|
|
23
|
+
- Rewrite the answer so it satisfies the stage goal and fixes the rejection reason.
|
|
24
|
+
"""
|
magma_core-2.0.0b1/src/magma_core/_prompts/coach/specific_failure/fix_text_only_answer_prompt.py
ADDED
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
# SPDX-License-Identifier: BSD-2-Clause
|
|
2
|
+
# Copyright (c) 2026, Loan Bernat
|
|
3
|
+
|
|
4
|
+
FIX_TEXT_ONLY_ANSWER = """\
|
|
5
|
+
You need to correct one step from a failed text-only stage.
|
|
6
|
+
|
|
7
|
+
In this stage, tools may be used before producing the final answer.
|
|
8
|
+
Use the previous diagnostic to propose a simple and effective correction.
|
|
9
|
+
|
|
10
|
+
IMPORTANT CONSTRAINTS:
|
|
11
|
+
- Propose the MINIMAL correction necessary.
|
|
12
|
+
- Do NOT modify previous steps.
|
|
13
|
+
- Do NOT invent facts.
|
|
14
|
+
- Do NOT mention the task context, diagnostic, rejection, or failure to the user.
|
|
15
|
+
- The corrected answer must keep the normal model answer format.
|
|
16
|
+
|
|
17
|
+
The objective of this stage is to answer to a question or fetch an information. It requires to use tools and to give an answer to the user.
|
|
18
|
+
|
|
19
|
+
{additional}
|
|
20
|
+
|
|
21
|
+
TASK CONTEXT:
|
|
22
|
+
{description}
|
|
23
|
+
|
|
24
|
+
AVAILABLE TOOLS:
|
|
25
|
+
{tools}
|
|
26
|
+
|
|
27
|
+
ORIGINAL USER INSTRUCTION:
|
|
28
|
+
{original_query}
|
|
29
|
+
|
|
30
|
+
CURRENT QUERY:
|
|
31
|
+
{query}
|
|
32
|
+
|
|
33
|
+
CURRENT MEMORY:
|
|
34
|
+
{memory}
|
|
35
|
+
|
|
36
|
+
REJECTED MODEL ANSWER:
|
|
37
|
+
{model_answer}
|
|
38
|
+
|
|
39
|
+
REPAIR INSTRUCTIONS:
|
|
40
|
+
|
|
41
|
+
If the current step should use a tool:
|
|
42
|
+
- Put exactly one tool call in the "action" field.
|
|
43
|
+
- The "say" field should briefly state what you are doing.
|
|
44
|
+
|
|
45
|
+
If the current step should answer the user:
|
|
46
|
+
- Put an empty object in the "action" field: {{}}
|
|
47
|
+
- The "say" field must be the final spoken answer.
|
|
48
|
+
|
|
49
|
+
The corrected step must:
|
|
50
|
+
- Respect the current query and memory.
|
|
51
|
+
- Use only available tools when a tool is needed.
|
|
52
|
+
- Restore a valid path toward satisfying the user instruction.
|
|
53
|
+
- Be locally correct from the current state.
|
|
54
|
+
|
|
55
|
+
REQUIRED OUTPUT FORMAT (STRICT)
|
|
56
|
+
|
|
57
|
+
A JSON object with the format: {format}.
|
|
58
|
+
"""
|