From 6b99422010c5d437775e2bc07a676e5b48db994a Mon Sep 17 00:00:00 2001 From: Lennart Gulikers Date: Tue, 18 Aug 2026 15:54:24 +0200 Subject: [PATCH 1/4] fix(runtime): forward config as kwarg in ingress evaluate path Signed-off-by: Lennart Gulikers --- .../src/mas/library/standard/plugins/design_patterns/linear.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library-standard/src/mas/library/standard/plugins/design_patterns/linear.py b/library-standard/src/mas/library/standard/plugins/design_patterns/linear.py index 6f43087f..2aaa8381 100644 --- a/library-standard/src/mas/library/standard/plugins/design_patterns/linear.py +++ b/library-standard/src/mas/library/standard/plugins/design_patterns/linear.py @@ -18,7 +18,7 @@ class DeterministicLinearPlugin(_DeterministicBase): plugin_id = "deterministic_linear@v1" mode = "linear" - def evaluate_next(self, q: QProduct, run: RunLedger, *, config: KernelConfig) -> list[EgressSymbol]: + def evaluate_next(self, q: QProduct, run: RunLedger, config: KernelConfig) -> list[EgressSymbol]: st = self._state() if not st.participants: return self._no_participants(q) From ce58e3ca38bc29455ded9f0020b11ed56f0e7266 Mon Sep 17 00:00:00 2001 From: Lennart Gulikers Date: Tue, 18 Aug 2026 16:00:23 +0200 Subject: [PATCH 2/4] fix(runtime): forward config as kwarg in ingress evaluate path Signed-off-by: Lennart Gulikers --- runtime/src/mas/runtime/kernel/ingress_step.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/runtime/src/mas/runtime/kernel/ingress_step.py b/runtime/src/mas/runtime/kernel/ingress_step.py index 52398451..266e9c56 100644 --- a/runtime/src/mas/runtime/kernel/ingress_step.py +++ b/runtime/src/mas/runtime/kernel/ingress_step.py @@ -94,7 +94,7 @@ def commit_engine_io_return( q.dp = DpState.EVALUATING apply_control_valid(q) coord_after_ingress(q) - return evaluate(q, run, config) + return evaluate(q, run, config=config) def apply_engine_io_return( @@ -203,6 +203,6 @@ def apply_engine_io_return( ) q.inflight_kind = "NONE" q.dp = DpState.EVALUATING - return evaluate(q, run, config) + return evaluate(q, run, config=config) return commit_engine_io_return(q, run, event, config=config, evaluate=evaluate) From 9d8d1360a7a7f04212077f93df42553267ce4a45 Mon Sep 17 00:00:00 2001 From: Lennart Gulikers Date: Tue, 18 Aug 2026 17:05:14 +0200 Subject: [PATCH 3/4] test(runtime): accept config kwarg in ingress evaluate stub Signed-off-by: Lennart Gulikers --- runtime/tests/test_parallel_tools.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/runtime/tests/test_parallel_tools.py b/runtime/tests/test_parallel_tools.py index 7bbeab41..80d9933c 100644 --- a/runtime/tests/test_parallel_tools.py +++ b/runtime/tests/test_parallel_tools.py @@ -102,7 +102,7 @@ def test_schedule_parallel_tools_egress_siblings_share_one_parent() -> None: text="ok", ) with runtime_binding(None, op): - apply_engine_io_return(q, run, event, config=config, evaluate=lambda *_: []) + apply_engine_io_return(q, run, event, config=config, evaluate=lambda *_, **__: []) ends = [ e From d3cf2deea61adfd4c3e541c15ba78fa99b97bf90 Mon Sep 17 00:00:00 2001 From: psterpu-c Date: Wed, 19 Aug 2026 10:42:27 +0300 Subject: [PATCH 4/4] fix: use workflow.entry as coordinator id instead of hardcoding moderator Signed-off-by: psterpu-c --- .../standard/plugins/design_patterns/base.py | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/library-standard/src/mas/library/standard/plugins/design_patterns/base.py b/library-standard/src/mas/library/standard/plugins/design_patterns/base.py index 640d06cd..1176a451 100644 --- a/library-standard/src/mas/library/standard/plugins/design_patterns/base.py +++ b/library-standard/src/mas/library/standard/plugins/design_patterns/base.py @@ -120,13 +120,17 @@ def evaluate_next(self, q: QProduct, run: RunLedger, *, config: KernelConfig) -> def _participants_from_spec(self, config: KernelConfig) -> list[str]: spec = getattr(config, "agent_spec", None) or {} wf = (spec.get("workflow") or {}) if isinstance(spec, dict) else {} + # The coordinator/entry node isn't always literally named "moderator" + # (e.g. sre-triage's entry node is "sre") — use workflow.entry when + # present so the coordinator never ends up delegating to itself. + coordinator_id = str(wf.get("entry") or "moderator").strip() or "moderator" - # 1) moderator.delegates_to (dynamic topology) + # 1) coordinator.delegates_to (dynamic topology) nodes = wf.get("nodes") or [] for node in nodes: if not isinstance(node, dict): continue - if str(node.get("id") or "").strip() != "moderator": + if str(node.get("id") or "").strip() != coordinator_id: continue delegates = node.get("delegates_to") or [] if isinstance(delegates, list): @@ -141,19 +145,19 @@ def _participants_from_spec(self, config: KernelConfig) -> list[str]: if out: return out - # 3) fallback: workflow.nodes excluding moderator + # 3) fallback: workflow.nodes excluding the coordinator out: list[str] = [] for node in nodes: if not isinstance(node, dict): continue node_id = str(node.get("id") or node.get("agent") or "").strip() - if not node_id or node_id == "moderator": + if not node_id or node_id == coordinator_id: continue out.append(node_id) if out: return out - # 4) fallback: agency agents list from MAS spec (exclude moderator/self) + # 4) fallback: agency agents list from MAS spec (exclude coordinator/self) agency = (spec.get("agency") or {}) if isinstance(spec, dict) else {} rows = agency.get("agents") or [] out = [] @@ -161,7 +165,7 @@ def _participants_from_spec(self, config: KernelConfig) -> list[str]: if not isinstance(row, dict): continue aid = str(row.get("id") or row.get("name") or "").strip() - if not aid or aid == "moderator": + if not aid or aid == coordinator_id: continue out.append(aid) return out