"""Step definitions for RemoteGraphManager scenarios in langgraph_platform_remote_graph.feature.""" from __future__ import annotations from behave import given, then, when # type: ignore[import-untyped] from behave.runner import Context # type: ignore[import-untyped] from cleveragents.langgraph.remote_graph import ( RemoteGraphConfig, RemoteGraphManager, RemoteGraphNotAvailableError, ) # --------------------------------------------------------------------------- # RemoteGraphManager — not configured # --------------------------------------------------------------------------- @given("a RemoteGraphManager with no platform URL") def step_manager_no_platform_url(context: Context) -> None: context.manager = RemoteGraphManager() @then("the manager should not be available") def step_manager_not_available(context: Context) -> None: assert not context.manager.is_available, ( "Expected manager.is_available=False but got True" ) @then("the manager platform_url should be None") def step_manager_platform_url_none(context: Context) -> None: assert context.manager.platform_url is None, ( f"Expected platform_url=None, got {context.manager.platform_url!r}" ) @when("I try to register a graph on the unconfigured manager") def step_try_register_unconfigured(context: Context) -> None: try: config = RemoteGraphConfig( graph_id="test-actor", platform_url="https://langgraph.example.com", ) context.manager.register_graph(config) context.manager_error = None except RemoteGraphNotAvailableError as exc: context.manager_error = exc @when("I try to list graphs on the unconfigured manager") def step_try_list_unconfigured(context: Context) -> None: try: context.manager.list_graphs() context.manager_error = None except RemoteGraphNotAvailableError as exc: context.manager_error = exc @when("I try to invoke a graph on the unconfigured manager") def step_try_invoke_unconfigured(context: Context) -> None: try: context.manager.invoke("test-actor", {}) context.manager_error = None except RemoteGraphNotAvailableError as exc: context.manager_error = exc @then("a RemoteGraphNotAvailableError should be raised") def step_remote_graph_not_available_error(context: Context) -> None: assert isinstance(context.manager_error, RemoteGraphNotAvailableError), ( f"Expected RemoteGraphNotAvailableError, got {type(context.manager_error)!r}" ) @when("I call health_check on the unconfigured manager") def step_health_check_unconfigured(context: Context) -> None: context.health_check_result = context.manager.health_check() @then("the health check result should be False") def step_health_check_false(context: Context) -> None: assert context.health_check_result is False, ( f"Expected health_check=False, got {context.health_check_result!r}" ) # --------------------------------------------------------------------------- # RemoteGraphManager — configured # --------------------------------------------------------------------------- @given('a RemoteGraphManager with platform URL "{platform_url}"') def step_manager_with_platform_url(context: Context, platform_url: str) -> None: context.manager = RemoteGraphManager(platform_url=platform_url) context.platform_url = platform_url @then("the manager should be available") def step_manager_available(context: Context) -> None: assert context.manager.is_available, ( "Expected manager.is_available=True but got False" ) @then('the manager platform_url should be "{expected}"') def step_manager_platform_url(context: Context, expected: str) -> None: assert context.manager.platform_url == expected, ( f"Expected platform_url={expected!r}, got {context.manager.platform_url!r}" ) @when('I register a graph with id "{graph_id}"') def step_register_graph(context: Context, graph_id: str) -> None: config = RemoteGraphConfig( graph_id=graph_id, platform_url=context.platform_url, ) context.manager.register_graph(config) context.last_registered_graph_id = graph_id context.last_registered_config = config @then('the graph "{graph_id}" should be registered') def step_graph_registered(context: Context, graph_id: str) -> None: graphs = context.manager.list_graphs() assert graph_id in graphs, ( f"Expected {graph_id!r} in registered graphs, got {graphs!r}" ) @when('I register graphs with ids "{graph_id_a}" and "{graph_id_b}"') def step_register_two_graphs( context: Context, graph_id_a: str, graph_id_b: str ) -> None: for gid in (graph_id_a, graph_id_b): config = RemoteGraphConfig( graph_id=gid, platform_url=context.platform_url, ) context.manager.register_graph(config) context.registered_graph_ids = [graph_id_a, graph_id_b] @then('list_graphs should return "{graph_id_a}" and "{graph_id_b}" in sorted order') def step_list_graphs_sorted(context: Context, graph_id_a: str, graph_id_b: str) -> None: graphs = context.manager.list_graphs() expected = sorted([graph_id_a, graph_id_b]) assert graphs == expected, f"Expected {expected!r}, got {graphs!r}" @then('get_graph_config for "{graph_id}" should return the config') def step_get_graph_config(context: Context, graph_id: str) -> None: config = context.manager.get_graph_config(graph_id) assert config.graph_id == graph_id, ( f"Expected config.graph_id={graph_id!r}, got {config.graph_id!r}" ) @when('I try to get config for unregistered graph "{graph_id}"') def step_try_get_config_unregistered(context: Context, graph_id: str) -> None: try: context.manager.get_graph_config(graph_id) context.manager_error = None except KeyError as exc: context.manager_error = exc @then("a KeyError should be raised for the unknown graph") def step_key_error_unknown_graph(context: Context) -> None: assert isinstance(context.manager_error, KeyError), ( f"Expected KeyError, got {type(context.manager_error)!r}" ) @when('I register then unregister graph "{graph_id}"') def step_register_then_unregister(context: Context, graph_id: str) -> None: config = RemoteGraphConfig( graph_id=graph_id, platform_url=context.platform_url, ) context.manager.register_graph(config) context.manager.unregister_graph(graph_id) @then('the graph "{graph_id}" should not be registered') def step_graph_not_registered(context: Context, graph_id: str) -> None: graphs = context.manager.list_graphs() assert graph_id not in graphs, ( f"Expected {graph_id!r} NOT in registered graphs, but found it in {graphs!r}" ) @when('I try to unregister an unknown graph "{graph_id}"') def step_try_unregister_unknown(context: Context, graph_id: str) -> None: try: context.manager.unregister_graph(graph_id) context.manager_error = None except KeyError as exc: context.manager_error = exc @then("a KeyError should be raised for the unregistered graph") def step_key_error_unregistered_graph(context: Context) -> None: assert isinstance(context.manager_error, KeyError), ( f"Expected KeyError, got {type(context.manager_error)!r}" ) @when('I try to invoke the registered graph "{graph_id}"') def step_try_invoke_registered(context: Context, graph_id: str) -> None: try: context.manager.invoke(graph_id, {"messages": []}) context.manager_error = None except RemoteGraphNotAvailableError as exc: context.manager_error = exc @then("a RemoteGraphNotAvailableError should be raised for the stub invocation") def step_remote_graph_not_available_stub(context: Context) -> None: assert isinstance(context.manager_error, RemoteGraphNotAvailableError), ( f"Expected RemoteGraphNotAvailableError, got {type(context.manager_error)!r}" ) @when('I try to invoke unregistered graph "{graph_id}"') def step_try_invoke_unregistered(context: Context, graph_id: str) -> None: try: context.manager.invoke(graph_id, {}) context.manager_error = None except KeyError as exc: context.manager_error = exc except RemoteGraphNotAvailableError as exc: context.manager_error = exc @then("a KeyError should be raised for the missing graph invocation") def step_key_error_missing_graph(context: Context) -> None: assert isinstance(context.manager_error, KeyError), ( f"Expected KeyError, got {type(context.manager_error)!r}" ) @when("I call health_check on the configured manager") def step_health_check_configured(context: Context) -> None: context.health_check_result = context.manager.health_check()