From 790d602449df6d73cb3d741908cab3246acf003e Mon Sep 17 00:00:00 2001 From: Connor Carpenter Date: Thu, 23 Jul 2026 07:58:25 -0700 Subject: [PATCH] refactor(api): consolidate proto files and trim EngineError Reduce the openengine/v1 file set from 10 to 8 by folding two small files into the domain file that owns their concern, and remove dead message/field surface. Package, message names, and field numbers are unchanged -- wire- and (whole-package) codegen-compatible. - Fold observability.proto into server.proto. Post-cleanup it held only load reporting (GetLoadRequest/LoadInfo/RankLoadInfo); "observability" was a misnomer. server.proto now covers static identity/capacity plus dynamic load -- everything the server reports about itself. - Fold input.proto into generation.proto, its sole remaining consumer, and delete the dead task-input types (TaskInput, MultimodalTaskInput, TaskInputType) orphaned when the non-generative task RPCs were removed. TokenIds/Modality/MediaItem move as-is. - Trim EngineError: drop `details` (never set or read by any engine/sidecar) and `retry_after_ms` (only ever absent), and the now-unused struct import. Keep `retryable` -- servers populate it (SGLang computes it from a 503) even though the sidecar does not yet read it. Sync docs/api.md and the proto README table. Validated with protoc and markdownlint-cli2. Signed-off-by: Connor Carpenter --- docs/api.md | 6 --- proto/openengine/v1/README.md | 6 +-- proto/openengine/v1/error.proto | 4 -- proto/openengine/v1/generation.proto | 29 +++++++++++- proto/openengine/v1/input.proto | 60 ------------------------- proto/openengine/v1/observability.proto | 40 ----------------- proto/openengine/v1/openengine.proto | 1 - proto/openengine/v1/server.proto | 32 ++++++++++++- 8 files changed, 60 insertions(+), 118 deletions(-) delete mode 100644 proto/openengine/v1/input.proto delete mode 100644 proto/openengine/v1/observability.proto diff --git a/docs/api.md b/docs/api.md index 2226237..2f463fb 100644 --- a/docs/api.md +++ b/docs/api.md @@ -847,8 +847,6 @@ message EngineError { ErrorCode code = 1; string message = 2; bool retryable = 3; - optional uint64 retry_after_ms = 4; - google.protobuf.Struct details = 5; } enum ErrorCode { @@ -890,7 +888,3 @@ KV-event or runtime-event subscription. No response may follow a terminal a failed drain state. `retryable` states whether the unchanged operation can succeed on retry. -`retry_after_ms` is present only for retryable errors and is the recommended -minimum delay; an explicit zero permits immediate retry. `details` contains -machine-readable error context. Stable detail keys are part of this API; -engine-specific keys should be namespaced to avoid collisions. diff --git a/proto/openengine/v1/README.md b/proto/openengine/v1/README.md index fcc090f..f809ec4 100644 --- a/proto/openengine/v1/README.md +++ b/proto/openengine/v1/README.md @@ -11,14 +11,12 @@ share the same package and together define the API. | File | Area | | --- | --- | | [`openengine.proto`](openengine.proto) | `Inference` and `Control` service declarations | -| [`input.proto`](input.proto) | Shared text, token, and multimodal inputs | -| [`server.proto`](server.proto) | Server identity, deployment capacity, engine roles, and parallelism | +| [`server.proto`](server.proto) | Server identity, deployment capacity, engine roles, parallelism, and load | | [`model.proto`](model.proto) | Model metadata and inference capabilities | -| [`generation.proto`](generation.proto) | Generation requests, parameters, streamed events, and usage | +| [`generation.proto`](generation.proto) | Generation inputs, requests, parameters, streamed events, and usage | | [`lora.proto`](lora.proto) | LoRA adapter lifecycle | | [`kv.proto`](kv.proto) | KV sessions, connector discovery, and cache events | | [`lifecycle.proto`](lifecycle.proto) | Health, abort, and drain operations | -| [`observability.proto`](observability.proto) | Load snapshots | | [`error.proto`](error.proto) | Terminal errors for accepted streaming requests | Generate bindings from every `.proto` file in this directory. Compiling only diff --git a/proto/openengine/v1/error.proto b/proto/openengine/v1/error.proto index dfba86f..2ca097b 100644 --- a/proto/openengine/v1/error.proto +++ b/proto/openengine/v1/error.proto @@ -7,16 +7,12 @@ syntax = "proto3"; package openengine.v1; -import "google/protobuf/struct.proto"; - // Accepted failures emit one terminal EngineError and close with OK. // Validation and transport failures use non-OK gRPC status instead. message EngineError { ErrorCode code = 1; string message = 2; bool retryable = 3; // Retry may succeed without changing the request. - optional uint64 retry_after_ms = 4; // Zero permits immediate retry. - google.protobuf.Struct details = 5; // Machine-readable context. } enum ErrorCode { diff --git a/proto/openengine/v1/generation.proto b/proto/openengine/v1/generation.proto index 119cdac..c1f81dd 100644 --- a/proto/openengine/v1/generation.proto +++ b/proto/openengine/v1/generation.proto @@ -1,7 +1,7 @@ // SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. // SPDX-License-Identifier: Apache-2.0 -// Generation requests, streamed events, and usage. +// Generation inputs, requests, streamed events, and usage. syntax = "proto3"; @@ -9,9 +9,34 @@ package openengine.v1; import "google/protobuf/struct.proto"; import "openengine/v1/error.proto"; -import "openengine/v1/input.proto"; import "openengine/v1/kv.proto"; +message TokenIds { + repeated uint32 ids = 1; +} + +// Multimodal modality discriminator. UNSPECIFIED means the sender left it unset. +enum Modality { + MODALITY_UNSPECIFIED = 0; + MODALITY_IMAGE = 1; + MODALITY_VIDEO = 2; + MODALITY_AUDIO = 3; +} + +// A single multimodal input. Exactly one `source` should be set. The engine +// owns fetch, decode, and preprocessing, so pre-decoded or RDMA media +// descriptors are not represented here. +message MediaItem { + Modality modality = 1; + oneof source { + string url = 2; // http(s):// -- engine fetches + string data_uri = 3; // data:;base64,<...> -- engine decodes + bytes raw_bytes = 4; // pre-fetched bytes -- engine still preprocesses + } + string mime_type = 5; // optional, hints raw_bytes decode + string uuid = 6; // optional caller id / mm_hash +} + message GenerateRequest { string request_id = 1; string model = 2; diff --git a/proto/openengine/v1/input.proto b/proto/openengine/v1/input.proto deleted file mode 100644 index da64f9e..0000000 --- a/proto/openengine/v1/input.proto +++ /dev/null @@ -1,60 +0,0 @@ -// SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. -// SPDX-License-Identifier: Apache-2.0 - -// Portable text, token, and multimodal inference inputs. - -syntax = "proto3"; - -package openengine.v1; - -message TokenIds { - repeated uint32 ids = 1; -} - -// Multimodal modality discriminator. UNSPECIFIED means the sender left it unset. -enum Modality { - MODALITY_UNSPECIFIED = 0; - MODALITY_IMAGE = 1; - MODALITY_VIDEO = 2; - MODALITY_AUDIO = 3; -} - -// A single multimodal input. Exactly one `source` should be set. The engine -// owns fetch, decode, and preprocessing, so pre-decoded or RDMA media -// descriptors are not represented here. -message MediaItem { - Modality modality = 1; - oneof source { - string url = 2; // http(s):// -- engine fetches - string data_uri = 3; // data:;base64,<...> -- engine decodes - bytes raw_bytes = 4; // pre-fetched bytes -- engine still preprocesses - } - string mime_type = 5; // optional, hints raw_bytes decode - string uuid = 6; // optional caller id / mm_hash -} - -// Text and token prompts may accompany media in a multimodal task input. -message MultimodalTaskInput { - oneof prompt { - string text = 1; - TokenIds token_ids = 2; - } - repeated MediaItem media = 3; -} - -// One independently correlated non-generative task input. -message TaskInput { - string item_id = 1; - oneof input { - string text = 2; - TokenIds token_ids = 3; - MultimodalTaskInput multimodal = 4; - } -} - -enum TaskInputType { - TASK_INPUT_TYPE_UNSPECIFIED = 0; - TASK_INPUT_TYPE_TEXT = 1; - TASK_INPUT_TYPE_TOKEN_IDS = 2; - TASK_INPUT_TYPE_MULTIMODAL = 3; -} diff --git a/proto/openengine/v1/observability.proto b/proto/openengine/v1/observability.proto deleted file mode 100644 index d254abd..0000000 --- a/proto/openengine/v1/observability.proto +++ /dev/null @@ -1,40 +0,0 @@ -// SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. -// SPDX-License-Identifier: Apache-2.0 - -// Load snapshots. - -syntax = "proto3"; - -package openengine.v1; - -import "google/protobuf/struct.proto"; - -message GetLoadRequest { - bool include_per_rank = 1; -} - -message LoadInfo { - string instance_id = 1; - optional uint64 timestamp_unix_nanos = 2; - optional uint32 running_requests = 3; - optional uint32 queued_requests = 4; - optional uint32 active_kv_sessions = 5; - optional uint64 used_kv_blocks = 6; - optional uint64 total_kv_blocks = 7; - optional uint64 running_tokens = 8; - optional uint64 waiting_tokens = 9; - optional uint32 prefill_batch_size = 10; - optional uint32 decode_batch_size = 11; - repeated RankLoadInfo ranks = 20; - google.protobuf.Struct attributes = 30; -} - -message RankLoadInfo { - optional uint32 data_parallel_rank = 1; - optional uint32 running_requests = 2; - optional uint32 queued_requests = 3; - optional uint64 used_kv_blocks = 4; - optional uint64 total_kv_blocks = 5; - optional uint32 prefill_batch_size = 6; - optional uint32 decode_batch_size = 7; -} diff --git a/proto/openengine/v1/openengine.proto b/proto/openengine/v1/openengine.proto index 101099d..4bbcae5 100644 --- a/proto/openengine/v1/openengine.proto +++ b/proto/openengine/v1/openengine.proto @@ -21,7 +21,6 @@ import "openengine/v1/kv.proto"; import "openengine/v1/lifecycle.proto"; import "openengine/v1/lora.proto"; import "openengine/v1/model.proto"; -import "openengine/v1/observability.proto"; import "openengine/v1/server.proto"; // Standard ASCII gRPC request metadata: diff --git a/proto/openengine/v1/server.proto b/proto/openengine/v1/server.proto index 1839caa..df04f3b 100644 --- a/proto/openengine/v1/server.proto +++ b/proto/openengine/v1/server.proto @@ -1,7 +1,7 @@ // SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. // SPDX-License-Identifier: Apache-2.0 -// Server identity, deployment capacity, engine role, and parallelism metadata. +// Server identity, deployment capacity, roles, parallelism, and load. syntax = "proto3"; @@ -55,3 +55,33 @@ message ParallelismInfo { optional uint32 data_parallel_start_rank = 5; optional uint32 decode_context_parallel_size = 6; // Ranks per decode-context group; at least 1. } + +message GetLoadRequest { + bool include_per_rank = 1; +} + +message LoadInfo { + string instance_id = 1; + optional uint64 timestamp_unix_nanos = 2; + optional uint32 running_requests = 3; + optional uint32 queued_requests = 4; + optional uint32 active_kv_sessions = 5; + optional uint64 used_kv_blocks = 6; + optional uint64 total_kv_blocks = 7; + optional uint64 running_tokens = 8; + optional uint64 waiting_tokens = 9; + optional uint32 prefill_batch_size = 10; + optional uint32 decode_batch_size = 11; + repeated RankLoadInfo ranks = 20; + google.protobuf.Struct attributes = 30; +} + +message RankLoadInfo { + optional uint32 data_parallel_rank = 1; + optional uint32 running_requests = 2; + optional uint32 queued_requests = 3; + optional uint64 used_kv_blocks = 4; + optional uint64 total_kv_blocks = 5; + optional uint32 prefill_batch_size = 6; + optional uint32 decode_batch_size = 7; +}