Repository navigation
Add read-only support for LLMInferenceService - #198
Conversation
There was a problem hiding this comment.
Pull request overview
Adds read-only LLMInferenceService visibility for #175.
Changes:
- Adds version-tolerant backend routes and permissions.
- Adds list/detail pages with status, topology, events, and YAML.
- Adds utility, backend, and Cypress tests.
Reviewed changes
Copilot reviewed 21 out of 21 changed files in this pull request and generated 5 comments.
Show a summary per file
| File | Description |
|---|---|
manifests/kustomize/base/cluster-role.yaml |
Grants read access. |
frontend/src/app/types/kfserving/llm-inference-service.ts |
Defines resource types. |
frontend/src/app/types/backend.ts |
Extends response types. |
frontend/src/app/shared/llm-inference-service.utils.ts |
Parses display values. |
frontend/src/app/shared/llm-inference-service.utils.spec.ts |
Tests parsing utilities. |
frontend/src/app/services/backend.service.ts |
Adds client methods. |
frontend/src/app/pages/llm-inference-service/llm-inference-service.module.ts |
Declares pages. |
frontend/src/app/pages/llm-inference-service/llm-inference-service.component.ts |
Implements listing logic. |
frontend/src/app/pages/llm-inference-service/llm-inference-service.component.html |
Renders the list. |
frontend/src/app/pages/llm-inference-service/llm-details/llm-details.component.ts |
Loads resource details. |
frontend/src/app/pages/llm-inference-service/llm-details/llm-details.component.scss |
Styles details. |
frontend/src/app/pages/llm-inference-service/llm-details/llm-details.component.html |
Renders details. |
frontend/src/app/pages/llm-inference-service/config.ts |
Configures table columns. |
frontend/src/app/pages/index/index.component.ts |
Adds navigation. |
frontend/src/app/app.module.ts |
Registers the module. |
frontend/src/app/app-routing.module.ts |
Adds routes. |
frontend/cypress/e2e/llm-inference-service.cy.ts |
Tests browser flows. |
frontend/__mocks__/kubeflow.ts |
Aligns mock typing. |
backend/apps/common/versions.py |
Defines supported versions. |
backend/apps/common/routes/get.py |
Adds read endpoints. |
backend/apps/common/routes/get_test.py |
Tests version detection. |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
|
Please do a rebase to master (not merge) for a clear commit history. |
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 23 out of 23 changed files in this pull request and generated 1 comment.
Suppressed comments (5)
frontend/src/app/shared/llm-inference-service.utils.ts:33
- This treats an omitted local
worker/prefillblock as single-node even whenbaseRefsinherits a multi-node or disaggregated workload. That makes the advertised “effective topology” incorrect for configuration-driven services. Derive reconciled topology fromstatus.workloadswhen available, and report an indeterminate/delegated state rather than “Single node” when referenced configurations have not been observed.
const hasWorker = !!spec?.worker;
const hasPrefill = !!spec?.prefill;
frontend/src/app/types/kfserving/llm-inference-service.ts:83
prefillis itself a workload specification with independentworker,replicas,parallelism, andscaling, but typing it as an opaque object means every new summary ignores those requested settings. A disaggregated service can therefore display only its decode configuration and even miss that its prefill workload is multi-node. Model a reusable workload interface and render decode and prefill settings separately.
template?: K8sObject;
worker?: K8sObject;
prefill?: K8sObject;
scaling?: LLMInferenceServiceScaling;
frontend/src/app/shared/llm-inference-service.utils.ts:239
- A Kubernetes condition may contain a message without a reason. In that valid case this produces the user-facing text
undefined: <message>. Prefix the message only whenreasonis present.
message: `${failed.reason}: ${failed.message}`,
frontend/src/app/pages/llm-inference-service/llm-inference-service.component.ts:138
- The parameter name
adoes not communicate that it contains the emitted table action. Rename it toactionEventso the handler remains understandable without relying on surrounding context.
public reactToAction(a: ActionEvent) {
const llmInferenceService = a.data as LLMInferenceServiceIR;
frontend/src/app/pages/llm-inference-service/llm-details/llm-details.component.html:56
- The details page exposes only the primary
status.url; it never rendersstatus.addresses, although the resource reports multiple reachable endpoints and #175 explicitly requires URL visibility. Secondary or origin-specific endpoints are therefore hidden. Render and deduplicate all reported addresses alongside the primary URL.
<lib-details-list-item
key="URL"
*ngIf="llmInferenceService.status?.url"
>
<a
Signed-off-by: Harshit Nayan <harshitacademia@gmail.com>
…ing info Signed-off-by: Harshit Nayan <harshitacademia@gmail.com>
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 23 out of 23 changed files in this pull request and generated no new comments.
Suppressed comments (5)
frontend/src/app/pages/llm-inference-service/llm-details/llm-details.component.ts:77
- Angular reuses this component when only route parameters change, but this branch leaves
detailsLoadedand the previous object intact and does not cancel in-flight object/event requests. The page can therefore show the old service under the new route name, and a slower response for the old route can overwrite the new result. Reset the view and switch/cancel the request stream when parameters change.
this.paramsSubscription = this.route.params.subscribe(params => {
this.namespaceService.updateSelectedNamespace(params.namespace);
this.serviceName = params.name;
this.namespace = params.namespace;
// Initial load before starting polling
this.getBackendObjects();
frontend/src/app/shared/llm-inference-service.utils.ts:33
- This defaults to
Single nodewheneverworkerandprefillare absent from the service's inline spec, butbaseRefscan inject either field during KServe's configuration merge. A service inheriting a multi-node or disaggregated configuration is therefore mislabeled, contrary to #175's effective-topology requirement. Resolve the referenced configuration chain (or use observed workload status where available) before deriving topology; an unresolved inherited topology must not be reported as single-node.
const hasWorker = !!spec?.worker;
const hasPrefill = !!spec?.prefill;
frontend/src/app/types/kfserving/llm-inference-service.ts:83
- KServe defines
prefillas a full workload specification, so it can independently containworker,replicas,scaling, andparallelism. Typing it loosely and only summarizing top-level workload fields makes those requested prefill settings invisible and can also misclassify a distributed prefill workload. Model the nested workload explicitly and render decode and prefill values separately.
template?: K8sObject;
worker?: K8sObject;
prefill?: K8sObject;
scaling?: LLMInferenceServiceScaling;
frontend/src/app/pages/llm-inference-service/llm-inference-service.component.ts:138
- The single-letter parameter
amakes the action-handling flow unnecessarily context-dependent. Rename it toactionEventso each field access is self-explanatory.
public reactToAction(a: ActionEvent) {
const llmInferenceService = a.data as LLMInferenceServiceIR;
frontend/src/app/pages/llm-inference-service/llm-details/llm-details.component.html:56
- The details page renders only the primary
status.urland ignores the already-modeledstatus.addresses. KServe can report multiple cluster-local/private/public addresses, and #175 explicitly requires URLs to be visible, so users still need raw YAML for the additional endpoints. Render every reported address, while retainingurlas the primary endpoint.
<lib-details-list-item
key="URL"
*ngIf="llmInferenceService.status?.url"
>
<a
…dling Signed-off-by: Harshit Nayan <harshitacademia@gmail.com>
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 31 out of 31 changed files in this pull request and generated no new comments.
Suppressed comments (3)
frontend/src/app/shared/llm-inference-service.utils.ts:46
- This returns the locally declared topology before considering observed workloads, so it can report the requested fragment instead of the effective merged topology required by #175. For example, if the local specification declares
prefilland abaseRefcontributes a decodeworker,topologyFromSpecreturnsDisaggregatedeven whenstatus.workloads.primaryis aLeaderWorkerSet. Combine the local and observed evidence rather than returning the first non-empty summary, and cover mixed local/inherited topology in the tests.
const fromSpec = topologyFromSpec(llmInferenceService?.spec);
if (fromSpec) {
return fromSpec;
frontend/src/app/shared/llm-inference-service.utils.ts:93
- The observed prefill workload can also be a
LeaderWorkerSet(for example whenprefill.workeris inherited through a base configuration). Checking onlyprimary.kindclassifies that effective topology as merelyDisaggregated. Include both observed workloads when detecting multi-node topology.
const hasWorker = workloads.primary?.kind === 'LeaderWorkerSet';
frontend/cypress/support/sse-mock.ts:1
- The newly exported types spell the initialism as
Sse, which is inconsistent with the establishedSSEService/SSEnaming infrontend/src/app/services/sse.service.ts:15. Rename the exported utility types toSSEWatchEventType,SSEWatchEvent, andSSEMockOptionsso the public test API uses one clear form.
export type SseWatchEventType =
Implements #175. The web application could already display InferenceService and InferenceGraph custom resources but had no visibility into LLMInferenceService, forcing anyone deploying a large language model to fall back to kubectl for basic questions such as whether the resource was accepted, how far the controller had progressed, and what topology and parallelism the specification actually requested. This change is scoped to reading; the create, edit and delete workflows are follow ups.
Assisted-By: Claude noreply@anthropic.com