diff --git a/src/gnuradio_mcp/middlewares/flowgraph.py b/src/gnuradio_mcp/middlewares/flowgraph.py index 405ca31..a0d74d3 100644 --- a/src/gnuradio_mcp/middlewares/flowgraph.py +++ b/src/gnuradio_mcp/middlewares/flowgraph.py @@ -1,9 +1,12 @@ from __future__ import annotations +from typing import Optional + from gnuradio.grc.core.FlowGraph import FlowGraph from gnuradio_mcp.middlewares.block import BlockMiddleware from gnuradio_mcp.models import BlockModel +from gnuradio_mcp.utils import get_unique_id class FlowGraphMiddleware: @@ -17,9 +20,11 @@ class FlowGraphMiddleware: for block in self._flowgraph.blocks ] - def add_block(self, block_type: str, block_name: str) -> None: + def add_block(self, block_type: str, block_name: Optional[str] = None) -> str: + block_name = block_name or get_unique_id(self._flowgraph.blocks) block = self._flowgraph.new_block(block_type) block.params["id"].set_value(block_name) + return block_name def remove_block(self, block_name: str) -> None: block = self._flowgraph.get_block(block_name) diff --git a/src/gnuradio_mcp/utils.py b/src/gnuradio_mcp/utils.py new file mode 100644 index 0000000..11428d2 --- /dev/null +++ b/src/gnuradio_mcp/utils.py @@ -0,0 +1,10 @@ +from itertools import count + + +def get_unique_id(flowgraph_blocks, base_id=""): + block_ids = set(b.name for b in flowgraph_blocks) + for index in count(): + block_id = "{}_{}".format(base_id, index) + if block_id not in block_ids: + break + return block_id diff --git a/tests/test_block.py b/tests/test_block.py index 5ea9d8b..dfc1b33 100644 --- a/tests/test_block.py +++ b/tests/test_block.py @@ -17,8 +17,8 @@ def flowgraph_middleware(platform: Platform): @pytest.fixture def block(flowgraph_middleware: FlowGraphMiddleware, block_key: str): - flowgraph_middleware.add_block(block_key, block_key) - return flowgraph_middleware._flowgraph.get_block(block_key) + block_name = flowgraph_middleware.add_block(block_key) + return flowgraph_middleware._flowgraph.get_block(block_name) def test_block_middleware_params(block: Block): diff --git a/tests/test_flowgraph.py b/tests/test_flowgraph.py index bb00b37..d784e4f 100644 --- a/tests/test_flowgraph.py +++ b/tests/test_flowgraph.py @@ -50,3 +50,38 @@ def test_flowgraph_initial_state( initial_blocks: list[BlockModel], ): assert flowgraph_middleware.blocks == initial_blocks + + +def test_block_naming(flowgraph_middleware: FlowGraphMiddleware, block_key: str): + # Explicit name + explicit_name = "my_custom_block_name" + flowgraph_middleware.add_block(block_key, explicit_name) + block = flowgraph_middleware._flowgraph.get_block(explicit_name) + assert block.params["id"].get_value() == explicit_name + # Remove for clean state + flowgraph_middleware._flowgraph.remove_element(block) + + # Implicit name (should use get_unique_id logic) + flowgraph_middleware.add_block(block_key) + # The last block added should be the last in the blocks list + last_block = flowgraph_middleware._flowgraph.blocks[-1] + # The id param should match the block's name + assert last_block.params["id"].get_value() == last_block.name + # Remove for clean state + flowgraph_middleware._flowgraph.remove_element(last_block) + + +def test_block_unique_names_for_same_type( + flowgraph_middleware: FlowGraphMiddleware, block_key: str +): + # Add two blocks of the same type without explicit names + flowgraph_middleware.add_block(block_key) + first_block = flowgraph_middleware._flowgraph.blocks[-1] + flowgraph_middleware.add_block(block_key) + second_block = flowgraph_middleware._flowgraph.blocks[-1] + # They should have different names + assert first_block.name != second_block.name + assert first_block.params["id"].get_value() != second_block.params["id"].get_value() + # Clean up + flowgraph_middleware._flowgraph.remove_element(first_block) + flowgraph_middleware._flowgraph.remove_element(second_block)