Skip to content

[Protocol]: Generalize the LoRA lifecycle into portable adapters #14

Description

@connorcarpenter15

Existing proposals

  • I searched the existing issues and did not find this proposal.

Intended consumers

Both direct engine clients and distributed frameworks.

Problem and use case

The current contract models only LoRA and only an ID, name, and absolute server-local path. It cannot represent prompt adapters, content-addressed/remote artifacts, base-model compatibility, revisions, asynchronous state, pinning/eviction, or restart reconciliation.

OpenEngine needs a generic adapter lifecycle and request-selection model that permits advertised combinations while retaining typed portable semantics.

Evidence from engine protocols

  • TensorRT-LLM accepts both LoRARequest and PromptAdapterRequest.
  • vLLM supports dynamic LoRA lifecycle and has distinct prompt adapters.
  • SGLang supports runtime LoRA load/unload and adapter enumeration.
  • Gateways need authoritative state after restart and immutable artifact identity; a local path is not a portable deployment identity.

Proposed contract

service OpenEngineAdapters {
  rpc LoadAdapter(LoadAdapterRequest) returns (stream AdapterOperationEvent);
  rpc UnloadAdapter(UnloadAdapterRequest)
      returns (stream AdapterOperationEvent);
  rpc GetAdapter(GetAdapterRequest) returns (AdapterInfo);
  rpc ListAdapters(ListAdaptersRequest) returns (ListAdaptersResponse);
  rpc PinAdapter(PinAdapterRequest) returns (AdapterInfo);
  rpc UnpinAdapter(UnpinAdapterRequest) returns (AdapterInfo);
}

enum AdapterKind {
  ADAPTER_KIND_UNSPECIFIED = 0;
  ADAPTER_KIND_LORA = 1;
  ADAPTER_KIND_PROMPT = 2;
}

message AdapterRef {
  string name = 1;
  string revision = 2;
  AdapterKind kind = 3;
}

message AdapterArtifact {
  string uri = 1;
  string digest = 2;
  string format = 3;
}

Generalize request selection to repeated adapter refs and generalize adapter identity in model capabilities and KV cache/events. Because the schema is pre-adoption, prefer direct replacement plus reserved field numbers; otherwise define precedence and deprecation unambiguously.

Presence, defaults, and validation

  • Name, base model, artifact URI, digest, and non-unspecified kind are required for load.
  • A revision may be empty only when an immutable digest supplies identity.
  • Local URI schemes are allowed only when advertised and authorized.
  • Idempotency key reuse with the same payload returns the operation; conflicting reuse fails.
  • Empty selection means base model; duplicates are invalid.
  • Multiple adapters are accepted only for advertised kind/count combinations.
  • Unknown, incompatible, or not-ready adapters fail before generation acceptance.

Request and response lifecycle

Load/unload are observable long-running operations with stable IDs, sequence numbers, progress/state events, and one terminal result. Stream cancellation detaches observation; clients reconcile through get/list and idempotent retries.

Unload defines an explicit reject/wait/force in-use policy, with no destructive default. Pin/unpin is idempotent. Generation pins the resolved immutable adapter set for its request lifetime. KV identity includes that complete set to avoid cache collisions.

Discovery and capability impact

Replace supports_lora with supported adapter kinds, separate lifecycle and request-selection capabilities, dynamic load/unload, pinning, source formats/schemes, capacity limits, per-request limits, and legal stacking combinations.

Alternatives considered

  • Parallel RPC families per adapter kind duplicate lifecycle and cannot express mixed/future kinds.
  • Keep source_path: assumes shared filesystem and omits immutable identity.
  • Untyped kind/options maps prevent portable validation.
  • Put artifact replication in OpenEngine: distribution belongs to the framework/artifact manager; OpenEngine starts from an engine-visible reference.

Out of scope

Adapter training, defining PEFT checkpoint contents, embedding download credentials, deployment-wide replication, or requiring every engine to support every kind.

Proposal checklist

  • The behavior is portable and does not expose one engine's internal scheduler model as the common API.
  • I have identified the corresponding documentation changes.
  • Add generic adapter messages/service and generation selection.
  • Generalize model capabilities and KV cache/event identity.
  • Reserve/deprecate LoRA-only fields and document migration.
  • Add conformance tests for idempotency, conflicts, failure, restart reconciliation, in-use unload, pinning, and unsupported combinations.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions