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.
Files changed (133) hide show
  1. magma_core-2.0.0b1/LICENSE +24 -0
  2. magma_core-2.0.0b1/PKG-INFO +64 -0
  3. magma_core-2.0.0b1/README.md +39 -0
  4. magma_core-2.0.0b1/pyproject.toml +43 -0
  5. magma_core-2.0.0b1/setup.cfg +4 -0
  6. magma_core-2.0.0b1/src/magma_core/__init__.py +4 -0
  7. magma_core-2.0.0b1/src/magma_core/_clients/__init__.py +7 -0
  8. magma_core-2.0.0b1/src/magma_core/_clients/client_base.py +41 -0
  9. magma_core-2.0.0b1/src/magma_core/_clients/client_factory.py +22 -0
  10. magma_core-2.0.0b1/src/magma_core/_clients/ollama_client.py +48 -0
  11. magma_core-2.0.0b1/src/magma_core/_prompts/__init__.py +2 -0
  12. magma_core-2.0.0b1/src/magma_core/_prompts/coach/diagnostic/coach_diagnose.py +120 -0
  13. magma_core-2.0.0b1/src/magma_core/_prompts/coach/diagnostic/diag_non_optimal.py +119 -0
  14. magma_core-2.0.0b1/src/magma_core/_prompts/coach/diagnostic/select_similar_cases.py +19 -0
  15. magma_core-2.0.0b1/src/magma_core/_prompts/coach/specific_failure/fix_say_prompt.py +24 -0
  16. magma_core-2.0.0b1/src/magma_core/_prompts/coach/specific_failure/fix_text_only_answer_prompt.py +58 -0
  17. magma_core-2.0.0b1/src/magma_core/_prompts/coach/specific_failure/format_prompt.py +36 -0
  18. magma_core-2.0.0b1/src/magma_core/_prompts/dataset/evaluate_leaf_prompt.py +178 -0
  19. magma_core-2.0.0b1/src/magma_core/_prompts/dataset/memory_prompt.py +287 -0
  20. magma_core-2.0.0b1/src/magma_core/_prompts/dataset/paraphrasing.py +140 -0
  21. magma_core-2.0.0b1/src/magma_core/_prompts/userSim/judge_prompt.py +61 -0
  22. magma_core-2.0.0b1/src/magma_core/_prompts/userSim/paraphrasing_prompt.py +107 -0
  23. magma_core-2.0.0b1/src/magma_core/configs/__init__.py +6 -0
  24. magma_core-2.0.0b1/src/magma_core/configs/config.py +170 -0
  25. magma_core-2.0.0b1/src/magma_core/configs/default_config.yaml +57 -0
  26. magma_core-2.0.0b1/src/magma_core/dataset_export.py +80 -0
  27. magma_core-2.0.0b1/src/magma_core/domain/__init__.py +7 -0
  28. magma_core-2.0.0b1/src/magma_core/domain/agent_call.py +96 -0
  29. magma_core-2.0.0b1/src/magma_core/protocol/__init__.py +6 -0
  30. magma_core-2.0.0b1/src/magma_core/protocol/agent.py +112 -0
  31. magma_core-2.0.0b1/src/magma_core/protocol/agent_coaching.py +141 -0
  32. magma_core-2.0.0b1/src/magma_core/protocol/agent_export.py +83 -0
  33. magma_core-2.0.0b1/src/magma_core/protocol/coaching.py +34 -0
  34. magma_core-2.0.0b1/src/magma_core/protocol/graph.py +49 -0
  35. magma_core-2.0.0b1/src/magma_core/protocol/payload/__init__.py +10 -0
  36. magma_core-2.0.0b1/src/magma_core/protocol/payload/base_payload.py +67 -0
  37. magma_core-2.0.0b1/src/magma_core/protocol/payload/coaching_common.py +113 -0
  38. magma_core-2.0.0b1/src/magma_core/protocol/payload/dataset_build_payload.py +138 -0
  39. magma_core-2.0.0b1/src/magma_core/protocol/payload/diagnosis_payload.py +249 -0
  40. magma_core-2.0.0b1/src/magma_core/protocol/payload/generic_coaching.py +148 -0
  41. magma_core-2.0.0b1/src/magma_core/protocol/payload/repr_instruction_variation.py +56 -0
  42. magma_core-2.0.0b1/src/magma_core/protocol/payload/user_sim_payload.py +102 -0
  43. magma_core-2.0.0b1/src/magma_core/serialization/__init__.py +24 -0
  44. magma_core-2.0.0b1/src/magma_core/serialization/spec.py +157 -0
  45. magma_core-2.0.0b1/src/magma_core/serialization/values.py +118 -0
  46. magma_core-2.0.0b1/src/magma_core/simulation/__init__.py +1 -0
  47. magma_core-2.0.0b1/src/magma_core/simulation/agents/__init__.py +10 -0
  48. magma_core-2.0.0b1/src/magma_core/simulation/agents/answers.py +98 -0
  49. magma_core-2.0.0b1/src/magma_core/simulation/constraints/__init__.py +1 -0
  50. magma_core-2.0.0b1/src/magma_core/simulation/constraints/base_constraint.py +46 -0
  51. magma_core-2.0.0b1/src/magma_core/simulation/data_structures/__init__.py +76 -0
  52. magma_core-2.0.0b1/src/magma_core/simulation/data_structures/env.py +298 -0
  53. magma_core-2.0.0b1/src/magma_core/simulation/data_structures/errors.py +3 -0
  54. magma_core-2.0.0b1/src/magma_core/simulation/data_structures/executor_agent_link.py +131 -0
  55. magma_core-2.0.0b1/src/magma_core/simulation/data_structures/observation.py +13 -0
  56. magma_core-2.0.0b1/src/magma_core/simulation/data_structures/situation.py +322 -0
  57. magma_core-2.0.0b1/src/magma_core/simulation/data_structures/tools.py +335 -0
  58. magma_core-2.0.0b1/src/magma_core/simulation/envs/__init__.py +7 -0
  59. magma_core-2.0.0b1/src/magma_core/simulation/envs/default_env.py +289 -0
  60. magma_core-2.0.0b1/src/magma_core/simulation/envs/default_multi_agent_env.py +23 -0
  61. magma_core-2.0.0b1/src/magma_core/simulation/errors/__init__.py +3 -0
  62. magma_core-2.0.0b1/src/magma_core/simulation/errors/base_error.py +92 -0
  63. magma_core-2.0.0b1/src/magma_core/simulation/executor/__init__.py +7 -0
  64. magma_core-2.0.0b1/src/magma_core/simulation/executor/executor.py +329 -0
  65. magma_core-2.0.0b1/src/magma_core/simulation/executor/mono_task_executor.py +209 -0
  66. magma_core-2.0.0b1/src/magma_core/simulation/goals/__init__.py +17 -0
  67. magma_core-2.0.0b1/src/magma_core/simulation/goals/base_goal.py +188 -0
  68. magma_core-2.0.0b1/src/magma_core/simulation/goals/failure.py +101 -0
  69. magma_core-2.0.0b1/src/magma_core/simulation/goals/positive.py +141 -0
  70. magma_core-2.0.0b1/src/magma_core/simulation/randomizer/__init__.py +4 -0
  71. magma_core-2.0.0b1/src/magma_core/simulation/randomizer/base_random_wrapper.py +101 -0
  72. magma_core-2.0.0b1/src/magma_core/simulation/randomizer/random_spec.py +37 -0
  73. magma_core-2.0.0b1/src/magma_core/simulation/randomizer/runtime_randomizer.py +488 -0
  74. magma_core-2.0.0b1/src/magma_core/simulation/randomizer/spec_generator.py +531 -0
  75. magma_core-2.0.0b1/src/magma_core/simulation/requests/__init__.py +3 -0
  76. magma_core-2.0.0b1/src/magma_core/simulation/requests/base_request.py +39 -0
  77. magma_core-2.0.0b1/src/magma_core/simulation/serialization/__init__.py +24 -0
  78. magma_core-2.0.0b1/src/magma_core/simulation/serialization/values.py +55 -0
  79. magma_core-2.0.0b1/src/magma_core/simulation/skills/__init__.py +38 -0
  80. magma_core-2.0.0b1/src/magma_core/simulation/skills/adapter.py +55 -0
  81. magma_core-2.0.0b1/src/magma_core/simulation/skills/skill.py +149 -0
  82. magma_core-2.0.0b1/src/magma_core/simulation/skills/skill_manager.py +654 -0
  83. magma_core-2.0.0b1/src/magma_core/simulation/skills/structure.py +591 -0
  84. magma_core-2.0.0b1/src/magma_core/simulation/stage/__init__.py +33 -0
  85. magma_core-2.0.0b1/src/magma_core/simulation/stage/base_stage.py +482 -0
  86. magma_core-2.0.0b1/src/magma_core/simulation/stage/environment_transition.py +35 -0
  87. magma_core-2.0.0b1/src/magma_core/simulation/stage/stage_composite.py +161 -0
  88. magma_core-2.0.0b1/src/magma_core/simulation/stage/stage_template.py +209 -0
  89. magma_core-2.0.0b1/src/magma_core/simulation/state/__init__.py +9 -0
  90. magma_core-2.0.0b1/src/magma_core/simulation/state/task_state.py +122 -0
  91. magma_core-2.0.0b1/src/magma_core/simulation/tasks/__init__.py +8 -0
  92. magma_core-2.0.0b1/src/magma_core/simulation/tasks/base_task.py +652 -0
  93. magma_core-2.0.0b1/src/magma_core/simulation/tasks/benchmark_task.py +133 -0
  94. magma_core-2.0.0b1/src/magma_core/simulation/tasks/definition.py +99 -0
  95. magma_core-2.0.0b1/src/magma_core/simulation/tasks_style.py +25 -0
  96. magma_core-2.0.0b1/src/magma_core/simulation/tools/__init__.py +7 -0
  97. magma_core-2.0.0b1/src/magma_core/simulation/tools/base_tool.py +183 -0
  98. magma_core-2.0.0b1/src/magma_core/simulation/tools/decorator.py +105 -0
  99. magma_core-2.0.0b1/src/magma_core/simulation/trajectory/__init__.py +6 -0
  100. magma_core-2.0.0b1/src/magma_core/simulation/trajectory/action_converter.py +289 -0
  101. magma_core-2.0.0b1/src/magma_core/simulation/utils/__init__.py +1 -0
  102. magma_core-2.0.0b1/src/magma_core/simulation/utils/env_utils.py +37 -0
  103. magma_core-2.0.0b1/src/magma_core/simulation/utils/gripper_utils.py +72 -0
  104. magma_core-2.0.0b1/src/magma_core/utils/__init__.py +4 -0
  105. magma_core-2.0.0b1/src/magma_core/utils/data_utils.py +81 -0
  106. magma_core-2.0.0b1/src/magma_core/utils/global_utils.py +240 -0
  107. magma_core-2.0.0b1/src/magma_core/utils/text_utils.py +192 -0
  108. magma_core-2.0.0b1/src/magma_core/workers/__init__.py +20 -0
  109. magma_core-2.0.0b1/src/magma_core/workers/base.py +13 -0
  110. magma_core-2.0.0b1/src/magma_core/workers/coaching_logs.py +25 -0
  111. magma_core-2.0.0b1/src/magma_core/workers/coaching_sessions.py +167 -0
  112. magma_core-2.0.0b1/src/magma_core/workers/human_coaching.py +143 -0
  113. magma_core-2.0.0b1/src/magma_core/workers/pool.py +105 -0
  114. magma_core-2.0.0b1/src/magma_core/workers/worker.py +293 -0
  115. magma_core-2.0.0b1/src/magma_core.egg-info/PKG-INFO +64 -0
  116. magma_core-2.0.0b1/src/magma_core.egg-info/SOURCES.txt +131 -0
  117. magma_core-2.0.0b1/src/magma_core.egg-info/dependency_links.txt +1 -0
  118. magma_core-2.0.0b1/src/magma_core.egg-info/requires.txt +20 -0
  119. magma_core-2.0.0b1/src/magma_core.egg-info/top_level.txt +1 -0
  120. magma_core-2.0.0b1/tests/test_base_error.py +34 -0
  121. magma_core-2.0.0b1/tests/test_base_request.py +57 -0
  122. magma_core-2.0.0b1/tests/test_base_task.py +511 -0
  123. magma_core-2.0.0b1/tests/test_config.py +158 -0
  124. magma_core-2.0.0b1/tests/test_data_utils.py +70 -0
  125. magma_core-2.0.0b1/tests/test_env_and_gripper_utils.py +99 -0
  126. magma_core-2.0.0b1/tests/test_goals.py +105 -0
  127. magma_core-2.0.0b1/tests/test_runtime_randomizer.py +451 -0
  128. magma_core-2.0.0b1/tests/test_stage_env_completion.py +82 -0
  129. magma_core-2.0.0b1/tests/test_stage_template.py +37 -0
  130. magma_core-2.0.0b1/tests/test_task_state.py +83 -0
  131. magma_core-2.0.0b1/tests/test_text_utils.py +69 -0
  132. magma_core-2.0.0b1/tests/test_tool_error_flags.py +707 -0
  133. 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,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+
@@ -0,0 +1,4 @@
1
+ # SPDX-License-Identifier: BSD-2-Clause
2
+ # Copyright (c) 2026, Loan Bernat
3
+
4
+ __version__ = "2.0.0b1"
@@ -0,0 +1,7 @@
1
+ # SPDX-License-Identifier: BSD-2-Clause
2
+ # Copyright (c) 2026, Loan Bernat
3
+
4
+ from .client_base import LLMClientBase
5
+ from .client_factory import ClientFactory
6
+
7
+ __all__ = ["LLMClientBase", "ClientFactory"]
@@ -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,2 @@
1
+ # SPDX-License-Identifier: BSD-2-Clause
2
+ # Copyright (c) 2026, Loan Bernat
@@ -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
+ """
@@ -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
+ """