graphmdo 0.1.2__tar.gz → 0.2.0__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 (62) hide show
  1. {graphmdo-0.1.2 → graphmdo-0.2.0}/.github/workflows/security.yml +15 -0
  2. {graphmdo-0.1.2 → graphmdo-0.2.0}/PKG-INFO +3 -2
  3. {graphmdo-0.1.2 → graphmdo-0.2.0}/README.md +2 -1
  4. {graphmdo-0.1.2 → graphmdo-0.2.0}/docs/api/optimization/optimizer.md +1 -1
  5. {graphmdo-0.1.2 → graphmdo-0.2.0}/docs/user-guide/quick-start.md +2 -1
  6. {graphmdo-0.1.2 → graphmdo-0.2.0}/main.py +5 -5
  7. {graphmdo-0.1.2 → graphmdo-0.2.0}/pyproject.toml +10 -0
  8. {graphmdo-0.1.2 → graphmdo-0.2.0}/src/mdo_framework/core/components.py +11 -11
  9. graphmdo-0.2.0/src/mdo_framework/core/evaluators.py +33 -0
  10. {graphmdo-0.1.2 → graphmdo-0.2.0}/src/mdo_framework/core/surrogates.py +6 -6
  11. {graphmdo-0.1.2 → graphmdo-0.2.0}/src/mdo_framework/core/topology.py +9 -12
  12. {graphmdo-0.1.2 → graphmdo-0.2.0}/src/mdo_framework/core/translator.py +7 -8
  13. {graphmdo-0.1.2 → graphmdo-0.2.0}/src/mdo_framework/db/client.py +5 -14
  14. {graphmdo-0.1.2 → graphmdo-0.2.0}/src/mdo_framework/db/graph_manager.py +11 -5
  15. {graphmdo-0.1.2 → graphmdo-0.2.0}/src/mdo_framework/optimization/optimizer.py +95 -99
  16. {graphmdo-0.1.2 → graphmdo-0.2.0}/src/services/execution/main.py +25 -17
  17. {graphmdo-0.1.2 → graphmdo-0.2.0}/src/services/graph/main.py +4 -2
  18. {graphmdo-0.1.2 → graphmdo-0.2.0}/src/services/optimization/main.py +62 -25
  19. {graphmdo-0.1.2 → graphmdo-0.2.0}/tests/conftest.py +1 -2
  20. {graphmdo-0.1.2 → graphmdo-0.2.0}/tests/test_components.py +12 -3
  21. {graphmdo-0.1.2 → graphmdo-0.2.0}/tests/test_db_client.py +2 -1
  22. {graphmdo-0.1.2 → graphmdo-0.2.0}/tests/test_integration.py +3 -3
  23. {graphmdo-0.1.2 → graphmdo-0.2.0}/tests/test_main.py +1 -1
  24. graphmdo-0.2.0/tests/test_optimizer.py +209 -0
  25. {graphmdo-0.1.2 → graphmdo-0.2.0}/tests/test_services.py +296 -63
  26. {graphmdo-0.1.2 → graphmdo-0.2.0}/tests/test_services_opt.py +1 -0
  27. {graphmdo-0.1.2 → graphmdo-0.2.0}/tests/test_surrogates.py +0 -6
  28. {graphmdo-0.1.2 → graphmdo-0.2.0}/tests/test_topology.py +1 -0
  29. {graphmdo-0.1.2 → graphmdo-0.2.0}/tests/test_translator.py +12 -2
  30. graphmdo-0.1.2/tests/test_optimizer.py +0 -162
  31. {graphmdo-0.1.2 → graphmdo-0.2.0}/.github/workflows/docs.yml +0 -0
  32. {graphmdo-0.1.2 → graphmdo-0.2.0}/.github/workflows/pypi-publish.yml +0 -0
  33. {graphmdo-0.1.2 → graphmdo-0.2.0}/.github/workflows/quality.yml +0 -0
  34. {graphmdo-0.1.2 → graphmdo-0.2.0}/.gitignore +0 -0
  35. {graphmdo-0.1.2 → graphmdo-0.2.0}/.pre-commit-config.yaml +0 -0
  36. {graphmdo-0.1.2 → graphmdo-0.2.0}/.python-version +0 -0
  37. {graphmdo-0.1.2 → graphmdo-0.2.0}/AGENTS.md +0 -0
  38. {graphmdo-0.1.2 → graphmdo-0.2.0}/Dockerfile +0 -0
  39. {graphmdo-0.1.2 → graphmdo-0.2.0}/LICENSE +0 -0
  40. {graphmdo-0.1.2 → graphmdo-0.2.0}/docker-compose.yml +0 -0
  41. {graphmdo-0.1.2 → graphmdo-0.2.0}/docs/api/core/components.md +0 -0
  42. {graphmdo-0.1.2 → graphmdo-0.2.0}/docs/api/core/surrogates.md +0 -0
  43. {graphmdo-0.1.2 → graphmdo-0.2.0}/docs/api/core/translator.md +0 -0
  44. {graphmdo-0.1.2 → graphmdo-0.2.0}/docs/api/db/client.md +0 -0
  45. {graphmdo-0.1.2 → graphmdo-0.2.0}/docs/api/db/graph_manager.md +0 -0
  46. {graphmdo-0.1.2 → graphmdo-0.2.0}/docs/dev-guide/contributing.md +0 -0
  47. {graphmdo-0.1.2 → graphmdo-0.2.0}/docs/index.md +0 -0
  48. {graphmdo-0.1.2 → graphmdo-0.2.0}/docs/technical-reference/architecture.md +0 -0
  49. {graphmdo-0.1.2 → graphmdo-0.2.0}/docs/technical-reference/microservices.md +0 -0
  50. {graphmdo-0.1.2 → graphmdo-0.2.0}/docs/user-guide/installation.md +0 -0
  51. {graphmdo-0.1.2 → graphmdo-0.2.0}/docs/user-guide/running-optimization.md +0 -0
  52. {graphmdo-0.1.2 → graphmdo-0.2.0}/mkdocs.yml +0 -0
  53. {graphmdo-0.1.2 → graphmdo-0.2.0}/src/mdo_framework/__init__.py +0 -0
  54. {graphmdo-0.1.2 → graphmdo-0.2.0}/src/mdo_framework/core/__init__.py +0 -0
  55. {graphmdo-0.1.2 → graphmdo-0.2.0}/src/mdo_framework/db/__init__.py +0 -0
  56. {graphmdo-0.1.2 → graphmdo-0.2.0}/src/mdo_framework/optimization/__init__.py +0 -0
  57. {graphmdo-0.1.2 → graphmdo-0.2.0}/src/services/__init__.py +0 -0
  58. {graphmdo-0.1.2 → graphmdo-0.2.0}/src/services/execution/__init__.py +0 -0
  59. {graphmdo-0.1.2 → graphmdo-0.2.0}/src/services/graph/__init__.py +0 -0
  60. {graphmdo-0.1.2 → graphmdo-0.2.0}/src/services/optimization/__init__.py +0 -0
  61. {graphmdo-0.1.2 → graphmdo-0.2.0}/tests/test_graph_manager.py +0 -0
  62. {graphmdo-0.1.2 → graphmdo-0.2.0}/uv.lock +0 -0
@@ -11,6 +11,21 @@ jobs:
11
11
  name: Build
12
12
  runs-on: ubuntu-latest
13
13
  steps:
14
+ - name: Free Disk Space (Ubuntu)
15
+ uses: jlumbroso/free-disk-space@main
16
+ with:
17
+ # This might take a few minutes, but it frees up ~30GB
18
+ tool-cache: false
19
+ android: true
20
+ dotnet: true
21
+ haskell: true
22
+ large-packages: true
23
+ docker-images: true
24
+ swap-storage: true
25
+
26
+ - name: Setup Docker
27
+ uses: docker/setup-buildx-action@v2
28
+
14
29
  - name: Checkout code
15
30
  uses: actions/checkout@v3
16
31
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: graphmdo
3
- Version: 0.1.2
3
+ Version: 0.2.0
4
4
  Summary: A dynamic, graph-driven Multidisciplinary Design Optimization (MDO) framework integrating FalkorDB, OpenMDAO, and multi-fidelity surrogate models.
5
5
  Author-email: jultou-raa <64092886+jultou-raa@users.noreply.github.com>, google-labs-jules-bot <161369871+google-labs-jules-bot@users.noreply.github.com>
6
6
  License-File: LICENSE
@@ -95,7 +95,8 @@ Once the graph is populated, you can run the optimization workflow. You need to
95
95
 
96
96
  ```python
97
97
  from mdo_framework.core.translator import GraphProblemBuilder
98
- from mdo_framework.optimization.optimizer import BayesianOptimizer, LocalEvaluator
98
+ from mdo_framework.optimization.optimizer import BayesianOptimizer
99
+ from mdo_framework.core.evaluators import LocalEvaluator
99
100
  from mdo_framework.core.topology import TopologicalAnalyzer
100
101
 
101
102
  # Define tool implementation
@@ -74,7 +74,8 @@ Once the graph is populated, you can run the optimization workflow. You need to
74
74
 
75
75
  ```python
76
76
  from mdo_framework.core.translator import GraphProblemBuilder
77
- from mdo_framework.optimization.optimizer import BayesianOptimizer, LocalEvaluator
77
+ from mdo_framework.optimization.optimizer import BayesianOptimizer
78
+ from mdo_framework.core.evaluators import LocalEvaluator
78
79
  from mdo_framework.core.topology import TopologicalAnalyzer
79
80
 
80
81
  # Define tool implementation
@@ -8,7 +8,7 @@
8
8
 
9
9
  # LocalEvaluator
10
10
 
11
- ::: mdo_framework.optimization.optimizer.LocalEvaluator
11
+ ::: mdo_framework.core.evaluators.LocalEvaluator
12
12
 
13
13
  # RemoteEvaluator
14
14
 
@@ -43,7 +43,8 @@ Once the graph is populated, you can run the optimization.
43
43
 
44
44
  ```python
45
45
  from mdo_framework.core.translator import GraphProblemBuilder
46
- from mdo_framework.optimization.optimizer import BayesianOptimizer, LocalEvaluator
46
+ from mdo_framework.optimization.optimizer import BayesianOptimizer
47
+ from mdo_framework.core.evaluators import LocalEvaluator
47
48
  from mdo_framework.core.topology import TopologicalAnalyzer
48
49
 
49
50
  # 1. Define Tool Implementation
@@ -1,13 +1,12 @@
1
+ from mdo_framework.core.evaluators import LocalEvaluator
1
2
  from mdo_framework.core.translator import GraphProblemBuilder
2
3
  from mdo_framework.db.graph_manager import GraphManager
3
- from mdo_framework.optimization.optimizer import BayesianOptimizer, LocalEvaluator
4
+ from mdo_framework.optimization.optimizer import BayesianOptimizer
4
5
 
5
6
 
6
7
  # --- Sellar Problem Functions ---
7
8
  def paraboloid_func(x, y):
8
- """
9
- f(x, y) = (x-3)**2 + xy + (y+4)**2 - 3
10
- """
9
+ """f(x, y) = (x-3)**2 + xy + (y+4)**2 - 3"""
11
10
  f_xy = (x - 3.0) ** 2 + x * y + (y + 4.0) ** 2 - 3.0
12
11
  c_xy = x - y
13
12
  return {"f_xy": f_xy, "c_xy": c_xy}
@@ -84,7 +83,8 @@ def main():
84
83
  try:
85
84
  result = optimizer.optimize(n_steps=10, n_init=5)
86
85
  print("Optimization Complete.")
87
- print("Best Result:", result)
86
+ print("Best Result:", result["best_parameters"])
87
+ print("Best Objectives:", result["best_objectives"])
88
88
  except Exception as e:
89
89
  print(f"Optimization failed: {e}")
90
90
 
@@ -43,3 +43,13 @@ dev = [
43
43
 
44
44
  [tool.hatch.build.targets.wheel]
45
45
  packages = ["src/mdo_framework", "src/services"]
46
+
47
+ [tool.coverage.run]
48
+ source = ["."]
49
+
50
+ [tool.coverage.report]
51
+ omit = [
52
+ "test/*",
53
+ "tests/*",
54
+ "**/__init__.py"
55
+ ]
@@ -2,16 +2,16 @@ import openmdao.api as om
2
2
 
3
3
 
4
4
  class ToolComponent(om.ExplicitComponent):
5
- """
6
- Generic OpenMDAO component that wraps a Python function.
7
- """
5
+ """Generic OpenMDAO component that wraps a Python function."""
8
6
 
9
7
  def initialize(self):
10
8
  self.options.declare("name", types=str, desc="Name of the tool")
11
9
  self.options.declare("func", types=object, desc="The function to execute")
12
10
  self.options.declare("inputs", types=list, desc="List of input variable names")
13
11
  self.options.declare(
14
- "outputs", types=list, desc="List of output variable names"
12
+ "outputs",
13
+ types=list,
14
+ desc="List of output variable names",
15
15
  )
16
16
  self.options.declare(
17
17
  "derivatives",
@@ -52,6 +52,7 @@ class ToolComponent(om.ExplicitComponent):
52
52
  # If func is: def my_func(x): return {"y": x * 2}
53
53
  # This compute block sets outputs["y"] = inputs["x"] * 2
54
54
  ```
55
+
55
56
  """
56
57
  func = self.options["func"]
57
58
  # Prepare inputs as a dictionary
@@ -69,14 +70,13 @@ class ToolComponent(om.ExplicitComponent):
69
70
  if len(self.options["outputs"]) == 1:
70
71
  output_name = self.options["outputs"][0]
71
72
  outputs[output_name] = result
73
+ elif isinstance(result, dict):
74
+ for name in self.options["outputs"]:
75
+ outputs[name] = result[name]
72
76
  else:
73
- if isinstance(result, dict):
74
- for name in self.options["outputs"]:
75
- outputs[name] = result[name]
76
- else:
77
- # If result is a tuple/list, assume order matches outputs
78
- for i, name in enumerate(self.options["outputs"]):
79
- outputs[name] = result[i]
77
+ # If result is a tuple/list, assume order matches outputs
78
+ for i, name in enumerate(self.options["outputs"]):
79
+ outputs[name] = result[i]
80
80
 
81
81
  def compute_partials(self, inputs, partials):
82
82
  if self.options["derivatives"]:
@@ -0,0 +1,33 @@
1
+ from typing import Any
2
+
3
+ import openmdao.api as om
4
+
5
+
6
+ class LocalEvaluator:
7
+ """Evaluates the design parameters locally using an OpenMDAO Problem instance.
8
+
9
+ Args:
10
+ problem: An instantiated OpenMDAO Problem object.
11
+
12
+ """
13
+
14
+ def __init__(self, problem: om.Problem):
15
+ self.problem = problem
16
+
17
+ def evaluate(
18
+ self,
19
+ parameters: dict[str, Any],
20
+ objectives: list[str],
21
+ ) -> dict[str, float]:
22
+ for name, val in parameters.items():
23
+ self.problem.set_val(name, val)
24
+ self.problem.run_model()
25
+
26
+ results = {}
27
+ for obj in objectives:
28
+ results[obj] = (
29
+ float(self.problem.get_val(obj)[0])
30
+ if hasattr(self.problem.get_val(obj), "__iter__")
31
+ else float(self.problem.get_val(obj))
32
+ )
33
+ return results
@@ -4,9 +4,7 @@ from smt.surrogate_models import KPLS, KRG
4
4
 
5
5
 
6
6
  class SMTSurrogate:
7
- """
8
- Wrapper for SMT surrogate models, supporting single and multi-fidelity.
9
- """
7
+ """Wrapper for SMT surrogate models, supporting single and multi-fidelity."""
10
8
 
11
9
  def __init__(self, model_type="KRG", multi_fidelity=False):
12
10
  self.model_type = model_type
@@ -20,14 +18,14 @@ class SMTSurrogate:
20
18
  x_lf: np.ndarray = None,
21
19
  y_lf: np.ndarray = None,
22
20
  ):
23
- """
24
- Trains the surrogate model.
21
+ """Trains the surrogate model.
25
22
 
26
23
  Args:
27
24
  xt: High-fidelity training inputs.
28
25
  yt: High-fidelity training outputs.
29
26
  x_lf: Low-fidelity training inputs (for multi-fidelity).
30
27
  y_lf: Low-fidelity training outputs (for multi-fidelity).
28
+
31
29
  """
32
30
  n_dims = xt.shape[1]
33
31
 
@@ -48,7 +46,9 @@ class SMTSurrogate:
48
46
  # Default n_comp=1 in SMT KPLS.
49
47
  n_comp = 1
50
48
  self.model = KPLS(
51
- theta0=[1e-2] * n_comp, n_comp=n_comp, print_global=False
49
+ theta0=[1e-2] * n_comp,
50
+ n_comp=n_comp,
51
+ print_global=False,
52
52
  )
53
53
  else:
54
54
  raise ValueError(f"Unknown model type: {self.model_type}")
@@ -2,18 +2,17 @@ from typing import Any
2
2
 
3
3
 
4
4
  class TopologicalAnalyzer:
5
- """
6
- Analyzes a KADMOS/CMDOWS-style graph schema recursively to extract
5
+ """Analyzes a KADMOS/CMDOWS-style graph schema recursively to extract
7
6
  the independent design variables and sub-graph components required
8
7
  to evaluate a specific target output.
9
8
  """
10
9
 
11
10
  def __init__(self, schema: dict[str, Any]):
12
- """
13
- Initializes the analyzer with the provided graph schema.
11
+ """Initializes the analyzer with the provided graph schema.
14
12
 
15
13
  Args:
16
14
  schema: Dictionary representing the full graph tools and variables.
15
+
17
16
  """
18
17
  self.schema = schema
19
18
  self.tools = {t["name"]: t for t in schema.get("tools", [])}
@@ -28,10 +27,10 @@ class TopologicalAnalyzer:
28
27
  self.var_sources[out_var].append(tool_name)
29
28
 
30
29
  def resolve_dependencies(
31
- self, target_outputs: list[str]
30
+ self,
31
+ target_outputs: list[str],
32
32
  ) -> tuple[list[str], list[dict[str, Any]]]:
33
- """
34
- Recursively resolve all dependencies needed to compute target_outputs.
33
+ """Recursively resolve all dependencies needed to compute target_outputs.
35
34
  Returns a tuple containing:
36
35
  1. A list of independent design variables (inputs without any tool source).
37
36
  2. A list of tool configurations required for execution.
@@ -67,9 +66,7 @@ class TopologicalAnalyzer:
67
66
  return design_vars, req_tools
68
67
 
69
68
  def extract_parameters(self, design_vars: list[str]) -> list[dict[str, Any]]:
70
- """
71
- Formats design variables into Ax-Platform ready parameter structures.
72
- """
69
+ """Formats design variables into Ax-Platform ready parameter structures."""
73
70
  parameters = []
74
71
  for var_name in design_vars:
75
72
  var_data = self.variables.get(var_name)
@@ -84,7 +81,7 @@ class TopologicalAnalyzer:
84
81
  "type": "choice",
85
82
  "values": var_data.get("choices", []),
86
83
  "value_type": var_data.get("value_type", "float"),
87
- }
84
+ },
88
85
  )
89
86
  else:
90
87
  parameters.append(
@@ -96,7 +93,7 @@ class TopologicalAnalyzer:
96
93
  var_data.get("upper", 1.0),
97
94
  ],
98
95
  "value_type": var_data.get("value_type", "float"),
99
- }
96
+ },
100
97
  )
101
98
 
102
99
  return parameters
@@ -1,4 +1,5 @@
1
- from typing import Any, Callable
1
+ from collections.abc import Callable
2
+ from typing import Any
2
3
 
3
4
  import openmdao.api as om
4
5
 
@@ -6,16 +7,14 @@ from mdo_framework.core.components import ToolComponent
6
7
 
7
8
 
8
9
  class GraphProblemBuilder:
9
- """
10
- Builds an OpenMDAO Problem from a graph schema dictionary.
11
- """
10
+ """Builds an OpenMDAO Problem from a graph schema dictionary."""
12
11
 
13
12
  def __init__(self, schema: dict[str, Any]):
14
- """
15
- Initializes the builder with the given graph schema.
13
+ """Initializes the builder with the given graph schema.
16
14
 
17
15
  Args:
18
16
  schema: Dictionary representing tools, inputs, and outputs.
17
+
19
18
  """
20
19
  """
21
20
  Args:
@@ -25,14 +24,14 @@ class GraphProblemBuilder:
25
24
  self.schema = schema
26
25
 
27
26
  def build_problem(self, tool_registry: dict[str, Callable]) -> om.Problem:
28
- """
29
- Constructs an OpenMDAO problem from the parsed schema.
27
+ """Constructs an OpenMDAO problem from the parsed schema.
30
28
 
31
29
  Args:
32
30
  tool_registry: Mapping of tool names to Python callables.
33
31
 
34
32
  Returns:
35
33
  An instantiated OpenMDAO Problem object.
34
+
36
35
  """
37
36
  """
38
37
  Constructs and sets up the OpenMDAO problem.
@@ -4,22 +4,18 @@ from falkordb import FalkorDB
4
4
 
5
5
 
6
6
  class FalkorDBClient:
7
- """
8
- Singleton class to manage the connection to the FalkorDB database.
9
- """
7
+ """Singleton class to manage the connection to the FalkorDB database."""
10
8
 
11
9
  _instance = None
12
10
 
13
11
  def __new__(cls):
14
12
  if cls._instance is None:
15
- cls._instance = super(FalkorDBClient, cls).__new__(cls)
13
+ cls._instance = super().__new__(cls)
16
14
  cls._instance._initialize()
17
15
  return cls._instance
18
16
 
19
17
  def _initialize(self):
20
- """
21
- Initializes the FalkorDB connection.
22
- """
18
+ """Initializes the FalkorDB connection."""
23
19
  host = os.getenv("FALKORDB_HOST", "localhost")
24
20
  port = int(os.getenv("FALKORDB_PORT", 6379))
25
21
  self.client = FalkorDB(host=host, port=port)
@@ -27,15 +23,10 @@ class FalkorDBClient:
27
23
  self.graph = self.client.select_graph(self.graph_name)
28
24
 
29
25
  def get_graph(self):
30
- """
31
- Returns the graph object for executing queries.
32
- """
26
+ """Returns the graph object for executing queries."""
33
27
  return self.graph
34
28
 
35
29
  def close(self):
36
- """
37
- Closes the connection.
38
- """
30
+ """Closes the connection."""
39
31
  # FalkorDB client handles connection pooling, but explicit close might be needed
40
32
  # depending on the implementation. For now, we rely on the client's management.
41
- pass
@@ -42,6 +42,7 @@ class GraphManager:
42
42
  gm.add_variable("wing_span", value=10.0, lower=5.0, upper=15.0, param_type="range", description="Wing span variable")
43
43
  gm.add_variable("material", value="aluminum", choices=["aluminum", "composite"], param_type="choice", value_type="str")
44
44
  ```
45
+
45
46
  """
46
47
  props = {
47
48
  "name": name,
@@ -78,6 +79,7 @@ class GraphManager:
78
79
  gm.add_tool("CFD_Solver", fidelity="high", version="1.2.0")
79
80
  gm.add_tool("Vortex_Lattice", fidelity="low")
80
81
  ```
82
+
81
83
  """
82
84
  props = {"name": name, "fidelity": fidelity}
83
85
  props.update(kwargs)
@@ -101,13 +103,15 @@ class GraphManager:
101
103
  ```python
102
104
  gm.connect_tool_to_output("CFD_Solver", "drag_coefficient")
103
105
  ```
106
+
104
107
  """
105
108
  query = """
106
109
  MATCH (t:Tool {name: $tool_name}), (v:Variable {name: $variable_name})
107
110
  MERGE (t)-[:OUTPUTS]->(v)
108
111
  """
109
112
  self.graph.query(
110
- query, params={"tool_name": tool_name, "variable_name": variable_name}
113
+ query,
114
+ params={"tool_name": tool_name, "variable_name": variable_name},
111
115
  )
112
116
 
113
117
  def connect_input_to_tool(self, variable_name: str, tool_name: str):
@@ -121,13 +125,15 @@ class GraphManager:
121
125
  ```python
122
126
  gm.connect_input_to_tool("wing_span", "CFD_Solver")
123
127
  ```
128
+
124
129
  """
125
130
  query = """
126
131
  MATCH (v:Variable {name: $variable_name}), (t:Tool {name: $tool_name})
127
132
  MERGE (v)-[:INPUTS_TO]->(t)
128
133
  """
129
134
  self.graph.query(
130
- query, params={"variable_name": variable_name, "tool_name": tool_name}
135
+ query,
136
+ params={"variable_name": variable_name, "tool_name": tool_name},
131
137
  )
132
138
 
133
139
  def get_tools(self) -> list[dict[str, Any]]:
@@ -177,8 +183,7 @@ class GraphManager:
177
183
  return [r[0] for r in result.result_set]
178
184
 
179
185
  def get_graph_schema(self) -> dict[str, Any]:
180
- """
181
- Returns a serializable dictionary representing the entire graph structure.
186
+ """Returns a serializable dictionary representing the entire graph structure.
182
187
 
183
188
  Returns:
184
189
  A dictionary containing 'tools' and 'variables' lists defining the topology.
@@ -188,6 +193,7 @@ class GraphManager:
188
193
  schema = gm.get_graph_schema()
189
194
  print(schema["tools"][0]["name"])
190
195
  ```
196
+
191
197
  """
192
198
  variables = self.get_variables()
193
199
 
@@ -214,7 +220,7 @@ class GraphManager:
214
220
  "fidelity": tool_node.properties.get("fidelity", "high"),
215
221
  "inputs": inputs,
216
222
  "outputs": outputs,
217
- }
223
+ },
218
224
  )
219
225
 
220
226
  return {"tools": tools, "variables": variables}