This is an automated email from the ASF dual-hosted git repository.
github-merge-queue[bot] pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/texera.git
The following commit(s) were added to refs/heads/main by this push:
new 12169c2cfe fix(agent-service): delete links targeting removed input
ports when shrinking input ports (#7349)
12169c2cfe is described below
commit 12169c2cfe5f92d0c492ae12d8eb2b53a6fec098
Author: Martin Vu <[email protected]>
AuthorDate: Thu Aug 13 21:30:34 2026 +0000
fix(agent-service): delete links targeting removed input ports when
shrinking input ports (#7349)
### What changes were proposed in this PR?
This PR fixes a bug in `WorkflowState.updateOperatorInputPorts` where
shrinking an operator's input port count left links targeting removed
input ports. The method now removes any links whose target port no
longer exists by calling `deleteLink`, preventing dangling links from
remaining in the workflow state.
A regression test was also added to verify that links targeting deleted
input ports are removed when the input port count is reduced.
### Any related issues, documentation, discussions?
Closes #7169
### How was this PR tested?
Added a regression test covering the case where an operator's input
ports are reduced while a link targets one of the removed ports.
Verified with:
```bash
bun test --test-name-pattern="removes links targeting input ports that are
dropped"
bun test
```
Before:
<img width="1716" height="1160" alt="image"
src="https://github.com/user-attachments/assets/bcfd23cb-aa4b-4f8e-87c1-46f0eda3e3e4"
/>
After:
<img width="1716" height="984" alt="image"
src="https://github.com/user-attachments/assets/f9937312-80f8-423b-8ec7-d7c522319b90"
/>
### Was this PR authored or co-authored using generative AI tooling?
Generated-by: ChatGPT (5.5 mini)
---
agent-service/src/agent/workflow-state.spec.ts | 24 ++++++++++++++++++++++++
agent-service/src/agent/workflow-state.ts | 9 +++++++++
2 files changed, 33 insertions(+)
diff --git a/agent-service/src/agent/workflow-state.spec.ts
b/agent-service/src/agent/workflow-state.spec.ts
index 2fd27af652..3c17b352de 100644
--- a/agent-service/src/agent/workflow-state.spec.ts
+++ b/agent-service/src/agent/workflow-state.spec.ts
@@ -341,6 +341,30 @@ describe("WorkflowState - updateOperatorInputPorts", () =>
{
test("returns false for a missing operator", () => {
expect(new WorkflowState().updateOperatorInputPorts("missing",
2)).toBe(false);
});
+
+ test("removes links targeting input ports that are dropped", () => {
+ const state = new WorkflowState();
+
+ state.addOperator(makeOperator("src"));
+ state.addOperator(
+ makeOperator("op1", {
+ inputPorts: [
+ { portID: "input-0", displayName: "Input 0" },
+ { portID: "input-1", displayName: "Input 1" },
+ ],
+ })
+ );
+
+ state.addLink({
+ linkID: "l1",
+ source: { operatorID: "src", portID: "output-0" },
+ target: { operatorID: "op1", portID: "input-1" },
+ });
+
+ state.updateOperatorInputPorts("op1", 1);
+
+ expect(state.getAllLinks().map(l => l.linkID)).toEqual([]);
+ });
});
describe("WorkflowState - workflow content round-trip", () => {
diff --git a/agent-service/src/agent/workflow-state.ts
b/agent-service/src/agent/workflow-state.ts
index d53692f33c..ef408eee24 100644
--- a/agent-service/src/agent/workflow-state.ts
+++ b/agent-service/src/agent/workflow-state.ts
@@ -189,6 +189,15 @@ export class WorkflowState {
inputPorts: newInputPorts,
};
this.operators.set(operatorId, updatedOperator);
+
+ const validInputPorts = new Set(newInputPorts.map(port => port.portID));
+
+ for (const link of this.getAllLinks()) {
+ if (link.target.operatorID === operatorId &&
!validInputPorts.has(link.target.portID)) {
+ this.deleteLink(link.linkID);
+ }
+ }
+
this.operatorPropertyChangeSubject.next({ operator: updatedOperator });
return true;
}