Replies: 1 comment
-
|
I suggest we put this discussion on hold, as there are ongoing efforts of refactoring the agent-service to make it well-designed, to name a few: #5753 #5751. After the refactoring, we can re-open the discussion, |
Beta Was this translation helpful? Give feedback.
0 replies
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Uh oh!
There was an error while loading. Please reload this page.
-
Summary — the contract drift problem
Texera now has two independent TypeScript clients of the same backend REST APIs: the Angular
frontendand theagent-service(the LLM agent that operates Texera on a user's behalf). Both call the same Scala backend endpoints (file-service, dashboard-service, workflow-compiling-service, workflow-execution-service), and both hand-redeclare the same contract — URL paths, request shapes, and response DTOs.That means each endpoint's contract exists in three places that must be kept in sync by hand:
frontend(AngularHttpClient, types incommon/type/*, URL constants in the dataset service)agent-service(fetch-based clients inagent-service/src/api/*, with its own duplicated interfaces)Concrete example — listing dataset versions:
DATASET_VERSION_RETRIEVE_LIST_URL+ aDatasetVersiontypelistDatasetVersions(...)building`/${did}/version/list`+ its ownDatasetVersioninterface inagent-service/src/api/dataset-api.tsThe path string and the DTO are duplicated across the frontend and the agent, and both can silently drift from the Scala backend. When the backend renames a field or changes a route, nothing fails at build time — the two TS clients just quietly go stale until something breaks at runtime. As the agent-service grows to cover more of Texera's surface (datasets, workflow CRUD, execution, operator metadata), this overlap with the frontend keeps growing.
We'd like to align on a standard for how endpoints/contracts are shared across clients before the duplication spreads further.
Important: what does NOT solve this (and why MCP is orthogonal)
This is closely related to #5610 (inline agent tools vs. a dedicated TexeraMCP server), so it's worth being explicit about the relationship, because the two are easy to conflate.
#5610 is about a different axis. It asks how the agent (an LLM) should consume Texera's capabilities — inline function-calling tools vs. MCP. That is an LLM-facing delivery question. The drift problem here is about how two programmatic HTTP clients avoid re-declaring the backend's contract. That is a client-contract question. They are orthogonal layers.
Adopting MCP does not remove this redundancy. If Texera's actions move behind a TexeraMCP server:
So MCP is a choice about how the agent talks to capabilities; it is not a contract-sharing strategy. The drift has to be solved one layer below MCP.
Note: the
@AgentTool/GET /api/agent-toolsmanifest idea proposed in #5610 is actually a drift solution in disguise — it's a "backend declares the contract once, clients derive from it" approach (the same family as Option C below). That's the connection worth pursuing: solve the contract layer first, and then the inline-vs-MCP decision in #5610 becomes a cheap downstream choice, because every client (frontend, agent, and any future MCP server) derives from one definition.A guiding principle
Both the frontend and the agent are clients of the same backend, which is the single source of truth. So the goal is not "share code between the frontend and the agent" — it's single-source the API contract and let every client derive from it.
And a key distinction: share the contract (types + endpoint paths), never the transport (the HTTP-calling code). The frontend uses Angular
HttpClient/Observables; the agent usesfetch/Promises. The transport legitimately differs per client; only the request/response shapes and URL paths are identical and worth deduplicating.Possible solutions
Option A — Status quo: hand-maintained copies
Keep duplicating manually.
Option B — Shared TypeScript contract package
A small workspace package (e.g.
@texera/api-contracts) holding only DTO interfaces + endpoint path builders (datasetVersionListPath(did)), consumed by both TS projects. No HTTP logic.Option C — Contract-first codegen from the backend (the industry standard)
The Scala backend emits a machine-readable contract (OpenAPI), and we generate typed TS clients for both consumers (
openapi-typescript/openapi-generator/orval). The backend is JAX-RS (Dropwizard/Jersey), which has first-class OpenAPI support via swagger annotations.@AgentToolmanifest idea — one backend-declared contract that the frontend, the agent, and any MCP server all derive from.Suggested direction (for discussion)
A pragmatic two-phase path:
api-contractsmodule for one API (e.g. datasets) as a pilot, to prove out the Angular-build integration on a small surface.Affected Area
Questions for the group
Related: #5610 (inline agent tools vs. TexeraMCP).
Beta Was this translation helpful? Give feedback.
All reactions