You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@texera.apache.org by gi...@apache.org on 2026/06/28 18:17:01 UTC

(texera) branch gh-readonly-queue/main/pr-5930-7610cb6c814b8a1186d360b52943189741f2a9e1 created (now 6fe63d569a)

This is an automated email from the ASF dual-hosted git repository.

github-merge-queue[bot] pushed a change to branch gh-readonly-queue/main/pr-5930-7610cb6c814b8a1186d360b52943189741f2a9e1
in repository https://gitbox.apache.org/repos/asf/texera.git


      at 6fe63d569a refactor(agent-service): remove dead checkout/headChange path (#5930)

This branch includes the following new commits:

     new 6fe63d569a refactor(agent-service): remove dead checkout/headChange path (#5930)

The 1 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.



(texera) 01/01: refactor(agent-service): remove dead checkout/headChange path (#5930)

Posted by gi...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

github-merge-queue[bot] pushed a commit to branch gh-readonly-queue/main/pr-5930-7610cb6c814b8a1186d360b52943189741f2a9e1
in repository https://gitbox.apache.org/repos/asf/texera.git

commit 6fe63d569a1fe2069b9cc70f4e2c46a723e0e915
Author: Jiadong Bai <43...@users.noreply.github.com>
AuthorDate: Sun Jun 28 11:16:39 2026 -0700

    refactor(agent-service): remove dead checkout/headChange path (#5930)
    
    ### What changes were proposed in this PR?
    
    Removes the step-checkout feature from agent-service, which was wired
    end-to-end but unreachable — nothing in the product ever invokes the
    frontend `checkoutStep()`, so the backend `/agents/:id/checkout`
    endpoint and its `headChange` WebSocket broadcast were never triggered.
    Removing the dead vertical slice:
    
    - `agent-service/src/server.ts` — drop the `POST /:id/checkout` route
    and the `headChange` / `workflowContent` members of the outgoing
    WebSocket-message type.
    - `agent-service/src/agent/texera-agent.ts` — drop
    `TexeraAgent.checkout()`.
    - `frontend/.../agent/agent.service.ts` — drop the `case "headChange"`
    WS handler and the unused `checkoutStep()` method.
    
    HEAD *tracking* is retained: `init`/`step` messages still carry
    `headId`, and the chat panel still walks the ancestor path from HEAD to
    render the visible step chain. Only the backward HEAD move (checkout) is
    removed.
    
    This branches from `main` and is independent of the type-refactor stack
    (#5751 → #5928/#5927). Note #5751 currently lists `headChange` as a
    server message; whichever merges second will drop it from the union — a
    trivial reconciliation.
    
    ### Any related issues, documentation, discussions?
    
    Closes #5942
    Part of #5747. Independent of the stack (branches from `main`).
    
    ### How was this PR tested?
    
    agent-service: `tsc --noEmit` clean, 93/93 `bun test` pass, prettier
    clean. Frontend: the removed `checkoutStep()` had zero callers and the
    `headChange` handler is now unreachable; verified no remaining
    `checkout`/`headChange` references and no orphaned imports.
    
    ### Was this PR authored or co-authored using generative AI tooling?
    
    Generated-by: Claude Opus 4.8 (1M context)
    
    Co-authored-by: Claude Opus 4.8 (1M context) <no...@anthropic.com>
---
 agent-service/src/agent/texera-agent.ts            | 12 +--------
 agent-service/src/server.spec.ts                   | 26 -------------------
 agent-service/src/server.ts                        | 29 ++--------------------
 agent-service/src/types/ws/server.ts               | 25 +------------------
 .../app/workspace/service/agent/agent.service.ts   | 28 ---------------------
 5 files changed, 4 insertions(+), 116 deletions(-)

diff --git a/agent-service/src/agent/texera-agent.ts b/agent-service/src/agent/texera-agent.ts
index 62cf20f145..ccd0545919 100644
--- a/agent-service/src/agent/texera-agent.ts
+++ b/agent-service/src/agent/texera-agent.ts
@@ -75,7 +75,7 @@ type ReActStepCallback = (step: ReActStep) => void;
 /**
  * A single Texera agent instance.
  *
- * Owns the conversation (ReAct step tree with HEAD/checkout semantics), the
+ * Owns the conversation (ReAct step tree with HEAD tracking), the
  * workflow being edited (`WorkflowState`), cached operator execution results
  * (`WorkflowResultState`), and the tool surface exposed to the LLM. Each call
  * to `sendMessage` drives one multi-step generation via the Vercel AI SDK,
@@ -298,16 +298,6 @@ export class TexeraAgent {
     return Array.from(this.stepsById.values()).filter(s => s.id !== INITIAL_STEP_ID);
   }
 
-  checkout(stepId: string): boolean {
-    const step = this.stepsById.get(stepId);
-    if (!step && stepId !== INITIAL_STEP_ID) return false;
-    this.head = stepId;
-    if (step?.afterWorkflowContent) {
-      this.workflowState.setWorkflowContent(step.afterWorkflowContent);
-    }
-    return true;
-  }
-
   setStepCallback(callback: ReActStepCallback | null): void {
     this.stepCallback = callback;
   }
diff --git a/agent-service/src/server.spec.ts b/agent-service/src/server.spec.ts
index 2024c63413..c1fdddc933 100644
--- a/agent-service/src/server.spec.ts
+++ b/agent-service/src/server.spec.ts
@@ -354,32 +354,6 @@ describe("agent read routes", () => {
   });
 });
 
-describe("checkout route", () => {
-  test("broadcasts and survives a websocket whose send throws", async () => {
-    const id = (await readJson<{ id: string }>(await createAgent())).id;
-    const agent = _getAgentForTests(id)!;
-    (agent as any).checkout = () => true;
-    (agent as any).getAllSteps = () => [];
-    // A failing socket must be dropped inside broadcastToAgentClients, not crash the request.
-    agent.addClient({
-      send: () => {
-        throw new Error("send failed");
-      },
-    } as any);
-
-    const res = await postJson(`${API}/agents/${id}/checkout`, { stepId: "step-1" });
-    expect(res.status).toBe(200);
-    expect((await readJson<{ headId: string }>(res)).headId).toBe("step-1");
-  });
-
-  test("returns 500 when the step cannot be found", async () => {
-    const id = (await readJson<{ id: string }>(await createAgent())).id;
-    (_getAgentForTests(id) as any).checkout = () => false;
-    const res = await postJson(`${API}/agents/${id}/checkout`, { stepId: "missing" });
-    expect(res.status).toBe(500);
-  });
-});
-
 describe("non-router routes", () => {
   test("unknown routes fall through to the catch-all error handler", async () => {
     const res = await getJson("/no-such-route");
diff --git a/agent-service/src/server.ts b/agent-service/src/server.ts
index 9370e7b5c1..030d27b95b 100644
--- a/agent-service/src/server.ts
+++ b/agent-service/src/server.ts
@@ -41,13 +41,7 @@ import type {
 } from "./types/agent";
 import { AgentState, OperatorResultSerializationMode } from "./types/agent";
 import type { WsClientCommand, WsServerEvent } from "./types/ws";
-import {
-  WsServerSnapshotEvent,
-  WsServerStepEvent,
-  WsServerStatusEvent,
-  WsServerErrorEvent,
-  WsServerHeadChangeEvent,
-} from "./types/ws";
+import { WsServerSnapshotEvent, WsServerStepEvent, WsServerStatusEvent, WsServerErrorEvent } from "./types/ws";
 import type { OperatorResultSummary } from "./types/execution";
 
 const agentStore = new Map<string, TexeraAgent>();
@@ -317,25 +311,6 @@ const agentsRouter = new Elysia({ prefix: "/agents" })
     return { status: "cleared" };
   })
 
-  .post("/:id/checkout", ({ params: { id }, body }) => {
-    const agent = getAgent(id);
-    const { stepId } = body as { stepId: string };
-    if (!stepId) throw new Error("stepId is required");
-
-    const success = agent.checkout(stepId);
-    if (!success) throw new Error(`Step ${stepId} not found or checkout failed`);
-
-    const allSteps = agent.getAllSteps();
-    const workflowContent = agent.getWorkflowState().getWorkflowContent();
-
-    broadcastToAgentClients(id, new WsServerHeadChangeEvent(stepId, allSteps, workflowContent));
-
-    return {
-      status: "checked out",
-      headId: stepId,
-    };
-  })
-
   .get("/:id/operator-types", ({ params: { id } }) => {
     const agent = getAgent(id);
     const metadataStore = agent.getMetadataStore();
@@ -614,7 +589,7 @@ function printStartupMessage(app: ReturnType<typeof buildApp>) {
     console.log("         Send: { type: 'WsClientPromptCommand', content: '...' }");
     console.log("         Send: { type: 'WsClientStopCommand' }");
     console.log(
-      "         Recv: { type: 'WsServerSnapshotEvent' | 'WsServerStepEvent' | 'WsServerStatusEvent' | 'WsServerErrorEvent' | 'WsServerHeadChangeEvent', ... }"
+      "         Recv: { type: 'WsServerSnapshotEvent' | 'WsServerStepEvent' | 'WsServerStatusEvent' | 'WsServerErrorEvent', ... }"
     );
   }
 
diff --git a/agent-service/src/types/ws/server.ts b/agent-service/src/types/ws/server.ts
index 019d2a1717..4fdf4e3a06 100644
--- a/agent-service/src/types/ws/server.ts
+++ b/agent-service/src/types/ws/server.ts
@@ -23,7 +23,6 @@
 // for you. `WsServerEvent` is their discriminated union.
 
 import type { AgentState, ReActStep } from "../agent";
-import type { WorkflowContent } from "../workflow";
 
 /**
  * Full state pushed once when a client connects: the agent's current lifecycle
@@ -60,27 +59,5 @@ export class WsServerErrorEvent {
   constructor(readonly error: string) {}
 }
 
-/**
- * Emitted after a checkout: HEAD moved, carrying the full step list and the
- * workflow snapshot at the new head.
- *
- * @deprecated Unused by the frontend/UI — nothing invokes the client's
- * `checkoutStep()`. The `/agents/:id/checkout` route (and its tests) still
- * broadcast it, so it remains reachable; do not build new UI on it.
- */
-export class WsServerHeadChangeEvent {
-  readonly type = "WsServerHeadChangeEvent";
-  constructor(
-    readonly headId: string,
-    readonly steps: ReActStep[],
-    readonly workflowContent?: WorkflowContent
-  ) {}
-}
-
 /** Discriminated union of every server -> client frame. */
-export type WsServerEvent =
-  | WsServerSnapshotEvent
-  | WsServerStepEvent
-  | WsServerStatusEvent
-  | WsServerErrorEvent
-  | WsServerHeadChangeEvent;
+export type WsServerEvent = WsServerSnapshotEvent | WsServerStepEvent | WsServerStatusEvent | WsServerErrorEvent;
diff --git a/frontend/src/app/workspace/service/agent/agent.service.ts b/frontend/src/app/workspace/service/agent/agent.service.ts
index 76ccbd4b9b..5e7c254f22 100644
--- a/frontend/src/app/workspace/service/agent/agent.service.ts
+++ b/frontend/src/app/workspace/service/agent/agent.service.ts
@@ -519,26 +519,6 @@ export class AgentService {
         }
         break;
 
-      case "WsServerHeadChangeEvent":
-        // HEAD moved (checkout) — update HEAD, visible steps, and workflow
-        if (message.headId !== undefined) {
-          tracking.headIdSubject.next(message.headId);
-        }
-        if (message.steps && Array.isArray(message.steps)) {
-          const steps = message.steps.map((s: any) => this.convertApiReActStep(s));
-          tracking.reActStepsSubject.next(steps);
-        }
-        // Update workflow content from agent service (ground truth)
-        if (message.workflowContent) {
-          tracking.wsWorkflowActive = true;
-          const workflow: Workflow = {
-            ...(message.workflowMetadata || tracking.workflowSubject.getValue() || {}),
-            content: message.workflowContent,
-          };
-          tracking.workflowSubject.next(workflow as Workflow);
-        }
-        break;
-
       case "WsServerErrorEvent":
         // Error occurred
         console.error(`Agent ${agentId} error:`, message.error);
@@ -1006,14 +986,6 @@ export class AgentService {
     return tracking ? tracking.headIdSubject.getValue() : null;
   }
 
-  /**
-   * Checkout to a specific step (move HEAD, restore workflow).
-   * The backend broadcasts headChange + visible steps via WebSocket to all clients.
-   */
-  public checkoutStep(agentId: string, stepId: string): Observable<any> {
-    return this.http.post(`${this.AGENT_API_BASE}/agents/${agentId}/checkout`, { stepId });
-  }
-
   /**
    * Get visible steps for an agent (current snapshot).
    */