Skip to content

Commit de1ccc2

Browse files
Merge branch 'main' into fix/per-prompt-mm-features
2 parents dad3ae3 + 2258e69 commit de1ccc2

62 files changed

Lines changed: 1074 additions & 606 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.github/workflows/md-link-check.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ jobs:
4949
uses: actions/checkout@v7
5050

5151
- name: Run lychee link checker
52-
uses: lycheeverse/lychee-action@v2.8.0
52+
uses: lycheeverse/lychee-action@v2.9.0
5353
with:
5454
# Exclude release-notes.d/ — fragments are sourced verbatim from
5555
# PR bodies; let the original PR's link check be authoritative.

.github/workflows/pr-rebase.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ jobs:
7070
7171
- name: Checkout base repo
7272
if: steps.check-access.outputs.skip != 'true'
73-
uses: actions/checkout@v4
73+
uses: actions/checkout@v7
7474
with:
7575
ref: ${{ steps.pr.outputs.base-ref }}
7676
fetch-depth: 0

CODEOWNERS

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,8 @@
2626
/apix/config/ @shmuelk @llm-d/router-maintainers
2727

2828
# Proxy sidecar
29-
/cmd/pd-sidecar/ @shmuelk @llm-d/router-maintainers
30-
/pkg/sidecar/ @shmuelk @llm-d/router-maintainers
29+
/cmd/pd-sidecar/ @shmuelk @roytman @llm-d/router-maintainers
30+
/pkg/sidecar/ @shmuelk @roytman @llm-d/router-maintainers
3131

3232
# SLO + latency-prediction subsystem
3333
/pkg/epp/framework/plugins/scheduling/filter/sloheadroomtier/ @kaushikmitr @llm-d/router-maintainers
@@ -47,3 +47,7 @@
4747
# Request handling
4848
/pkg/epp/framework/interface/requesthandling/ @zetxqx @llm-d/router-maintainers
4949
/pkg/epp/framework/plugins/requesthandling/ @zetxqx @llm-d/router-maintainers
50+
51+
# Coordinator
52+
/cmd/coordinator/ @shmuelk @roytman @llm-d/router-maintainers
53+
/pkg/coordinator/ @shmuelk @roytman @llm-d/router-maintainers

Dockerfile.builder

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,11 @@ ENV ENVTEST_K8S_VERSION=${ENVTEST_K8S_VERSION}
6363
# /usr/local/bin.
6464
RUN GOBIN=/usr/local/bin go install golang.org/x/vuln/cmd/govulncheck@${GOVULNCHECK_VERSION}
6565

66+
# Install the ginkgo CLI. Build-time install ensures runtime invocations under
67+
# --userns=keep-id / -u <uid> can use the binary without writing to root-owned
68+
# /usr/local/bin.
69+
RUN GOBIN=/usr/local/bin go install github.com/onsi/ginkgo/v2/ginkgo@v2.28.3
70+
6671
# Go caches are mounted as volumes at runtime for persistence across image rebuilds.
6772
# Directories are created with open permissions so non-root users (docker -u) can write.
6873
ENV GOMODCACHE=/go/pkg/mod

README.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
[![Go Reference](https://pkg.go.dev/badge/github.com/llm-d/llm-d-router.svg)](https://pkg.go.dev/github.com/llm-d/llm-d-router)
33
[![License](https://img.shields.io/github/license/llm-d/llm-d-router)](/LICENSE)
44
[![Join Slack](https://img.shields.io/badge/Join_Slack-blue?logo=slack)](https://llm-d.slack.com/archives/C08SBNRRSBD)
5+
[![FOSSA Status](https://app.fossa.com/api/projects/git%2Bgithub.com%2Fllm-d%2Fllm-d-router.svg?type=shield)](https://app.fossa.com/projects/git%2Bgithub.com%2Fllm-d%2Fllm-d-router?ref=badge_shield)
56

67
# llm-d Router
78

@@ -90,3 +91,7 @@ Contributions are welcome!
9091
[Google Meet]:https://meet.google.com/ozx-goao-cxh
9192
[Meeting Notes]:https://docs.google.com/document/d/1Pf3x7ZM8nNpU56nt6CzePAOmFZ24NXDeXyaYb565Wq4
9293
[#sig-router]:https://llm-d.slack.com/?redir=%2Fmessages%2Fsig-router
94+
95+
96+
## License
97+
[![FOSSA Status](https://app.fossa.com/api/projects/git%2Bgithub.com%2Fllm-d%2Fllm-d-router.svg?type=large)](https://app.fossa.com/projects/git%2Bgithub.com%2Fllm-d%2Fllm-d-router?ref=badge_large)

cmd/coordinator/main.go

Lines changed: 2 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@ package main
1919
import (
2020
"context"
2121
"errors"
22-
"fmt"
2322
"net/http"
2423
"os"
2524
"os/signal"
@@ -34,8 +33,8 @@ import (
3433
"github.com/llm-d/llm-d-router/pkg/coordinator/config"
3534
"github.com/llm-d/llm-d-router/pkg/coordinator/gateway"
3635
"github.com/llm-d/llm-d-router/pkg/coordinator/pipeline"
36+
"github.com/llm-d/llm-d-router/pkg/coordinator/pipeline/builder"
3737
"github.com/llm-d/llm-d-router/pkg/coordinator/server"
38-
"github.com/llm-d/llm-d-router/pkg/coordinator/steps"
3938
)
4039

4140
func main() {
@@ -82,7 +81,7 @@ func main() {
8281

8382
gwClient := gateway.New(cfg.Gateway)
8483

85-
steps, err := buildPipeline(cfg, gwClient)
84+
steps, err := builder.Build(cfg, gwClient)
8685
if err != nil {
8786
log.Error(err, "failed to build pipeline")
8887
os.Exit(1)
@@ -128,53 +127,3 @@ func serveUntilSignal(srv *server.Server, shutdownTimeout time.Duration) error {
128127
}
129128
return nil
130129
}
131-
132-
// validatePipeline rejects configurations that cannot work before any step runs.
133-
// The tokens-in format (use_openai_format=false) sends token IDs that only the
134-
// render step produces, so it requires a render step in the pipeline.
135-
func validatePipeline(p config.PipelineConfig) error {
136-
if p.UseOpenAIFormat {
137-
return nil
138-
}
139-
for _, s := range p.Steps {
140-
if s.Type == steps.RenderStepName {
141-
return nil
142-
}
143-
}
144-
return fmt.Errorf("pipeline.use_openai_format=false requires a %q step (the tokens-in format sends token IDs that render produces)", steps.RenderStepName)
145-
}
146-
147-
func mergeConnectorDefaults(params map[string]any, kvConnector, ecConnector string) map[string]any {
148-
out := make(map[string]any, len(params))
149-
for k, v := range params {
150-
out[k] = v
151-
}
152-
if _, ok := out[steps.ParamKVConnector]; !ok && kvConnector != "" {
153-
out[steps.ParamKVConnector] = kvConnector
154-
}
155-
if _, ok := out[steps.ParamECConnector]; !ok && ecConnector != "" {
156-
out[steps.ParamECConnector] = ecConnector
157-
}
158-
return out
159-
}
160-
161-
func buildPipeline(cfg *config.Config, gwClient *gateway.Client) ([]pipeline.Step, error) {
162-
if err := validatePipeline(cfg.Pipeline); err != nil {
163-
return nil, err
164-
}
165-
166-
var steps []pipeline.Step
167-
for _, stepCfg := range cfg.Pipeline.Steps {
168-
params := mergeConnectorDefaults(stepCfg.Params, cfg.Pipeline.KVConnector, cfg.Pipeline.ECConnector)
169-
if _, ok := params["use_openai_format"]; !ok {
170-
params["use_openai_format"] = cfg.Pipeline.UseOpenAIFormat
171-
}
172-
step, err := pipeline.Build(stepCfg.Type, gwClient, params)
173-
if err != nil {
174-
return nil, err
175-
}
176-
177-
steps = append(steps, step)
178-
}
179-
return steps, nil
180-
}

cmd/epp/runner/runner.go

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -355,7 +355,7 @@ func (r *Runner) setup(ctx context.Context, cfg *rest.Config, opts *runserver.Op
355355
return nil, nil, err
356356
}
357357

358-
ds, err := setupDatastore(ctx, epf, int32(opts.ModelServerMetricsPort), startCrdReconcilers,
358+
ds, err := setupDatastore(ctx, epf, startCrdReconcilers,
359359
gknn.Namespace, gknn.Name, opts.EndpointSelector, opts.EndpointTargetPorts)
360360
if err != nil {
361361
setupLog.Error(err, "Failed to setup datastore")
@@ -520,18 +520,18 @@ func NewEndpointPoolFromOptions(
520520
return pool, nil
521521
}
522522

523-
func setupDatastore(ctx context.Context, epFactory datalayer.EndpointFactory, modelServerMetricsPort int32,
523+
func setupDatastore(ctx context.Context, epFactory datalayer.EndpointFactory,
524524
startCrdReconcilers bool, namespace, name string, endpointSelector labels.Selector, endpointTargetPorts []int) (datastore.Datastore, error) {
525525

526526
if startCrdReconcilers {
527-
return datastore.NewDatastore(ctx, epFactory, modelServerMetricsPort), nil
527+
return datastore.NewDatastore(ctx, epFactory), nil
528528
}
529529
endpointPool, err := NewEndpointPoolFromOptions(namespace, name, endpointSelector, endpointTargetPorts)
530530
if err != nil {
531531
setupLog.Error(err, "Failed to construct endpoint pool from options")
532532
return nil, err
533533
}
534-
return datastore.NewDatastore(ctx, epFactory, modelServerMetricsPort).WithEndpointPool(endpointPool), nil
534+
return datastore.NewDatastore(ctx, epFactory).WithEndpointPool(endpointPool), nil
535535
}
536536

537537
// registerInTreePlugins registers the factory functions of all known plugins
@@ -904,7 +904,7 @@ func (r *Runner) runWithFileDiscovery(ctx context.Context, opts *runserver.Optio
904904
poolName = "epp"
905905
}
906906
pool := datalayer.NewEndpointPool(namespace, poolName)
907-
ds := datastore.NewDatastore(ctx, epf, int32(opts.ModelServerMetricsPort)).WithEndpointPool(pool)
907+
ds := datastore.NewDatastore(ctx, epf).WithEndpointPool(pool)
908908

909909
// On bare metal / Slurm / Ray (or any deployment without the K8s Downward
910910
// API), neither --pool-namespace nor the NAMESPACE env var is set, so the

deploy/environments/dev/e2e-infra/services.yaml

Lines changed: 0 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -20,22 +20,6 @@ spec:
2020
---
2121
apiVersion: v1
2222
kind: Service
23-
metadata:
24-
name: e2e-epp-health
25-
spec:
26-
selector:
27-
app: e2e-epp
28-
ports:
29-
- name: health
30-
protocol: TCP
31-
port: 9003
32-
targetPort: 9003
33-
nodePort: 30081
34-
appProtocol: http2
35-
type: NodePort
36-
---
37-
apiVersion: v1
38-
kind: Service
3923
metadata:
4024
name: e2e-epp-metrics
4125
spec:

docs/architecture.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
- [`SchedulingProfiles` Configuration](#schedulingprofiles-configuration)
1313
- [Available plugins](#available-plugins)
1414
- [Metric Scraping](#metric-scraping)
15-
- [Disaggregated Encode/Prefill/Decode (E/P/D)](#disaggregated-encodeprefilldecodesepd-epd)
15+
- [Disaggregated Encode/Prefill/Decode (E/P/D)](#disaggregated-encodeprefilldecode-epd)
1616
- [InferencePool & InferenceModel Design](#inferencepool--inferencemodel-design)
1717
- [Current Assumptions](#current-assumptions)
1818
- [References](#references)
@@ -304,6 +304,6 @@ Enable chunked decode via the pd-sidecar flag:
304304

305305
## References
306306

307-
- [GIE Spec](../README.md#relation-to-gie-igw)
307+
- [Gateway API Inference Extension](https://github.com/kubernetes-sigs/gateway-api-inference-extension)
308308
- [Envoy External Processing](https://www.envoyproxy.io/docs/envoy/latest/configuration/http/http_filters/ext_proc_filter)
309309
- [EPP Container Sizing Guide](./operations.md)

docs/communication.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ However, it is relatively new and may contain bugs. The `/v1/chat/completions` f
1919
- [EPP-Phase Header and Routing](#epp-phase-header-and-routing)
2020
- [Request Format Configuration](#request-format-configuration)
2121
- [Completions Requests (/v1/completions)](#completions-requests-v1completions)
22-
- [Text-Only Requests (no images)](#text-only-requests-no-images)
22+
- [Text-Only Requests (no images)](#text-only-requests-no-images-v1chatcompletions)
2323
- [Questions](#questions)
2424

2525
## Pipeline Overview

0 commit comments

Comments
 (0)