dynamo.frontend

OpenAI-compatible HTTP frontend, argument parsing, and pre/post-processing.

View as Markdown

dynamo.frontend publishes 12 classes and 31 functions. Source: components/src/dynamo/frontend/__init__.py

No summary available.

1from dynamo.frontend.vllm_processor import EngineFactory
1EngineFactory(config: FrontendConfig, flags: Namespace)

components/src/dynamo/frontend/vllm_processor.py#L931

Public methods

init

1__init__(config: FrontendConfig, flags: Namespace)

No summary available.

source

chat_engine_factory

1chat_engine_factory(instance_id: ModelCardInstanceId, mdc: ModelDeploymentCard, routed_engine: RoutedEngine) -> PythonAsyncEngine

Called by Rust when a model is discovered.

source

Frontend configuration parameters.

1from dynamo.frontend.frontend_args import FrontendArgGroup

components/src/dynamo/frontend/frontend_args.py#L175

Public methods

add_arguments

1add_arguments(parser) -> None

No summary available.

source

Configuration for the Dynamo frontend.

1from dynamo.frontend.frontend_args import FrontendConfig

components/src/dynamo/frontend/frontend_args.py#L53

Public methods

validate

1validate() -> None

No summary available.

source

Raised by preprocess workers for user-facing errors (e.g., n!=1).

1from dynamo.frontend.utils import PreprocessError
1PreprocessError(message: str)

Carries a plain message because the worker→main-process boundary pickles the exception; the main process re-raises a Dynamo-typed exception so PyO3 can route it through the proper backend-error path.

components/src/dynamo/frontend/utils.py#L83

Public methods

init

1__init__(message: str)

No summary available.

source

No summary available.

1from dynamo.frontend.prepost import PreprocessResult
1PreprocessResult(request_for_sampling: ChatCompletionRequest, tool_parser: ToolParser | None, chat_template_kwargs: dict[str, Any], engine_prompt: dict[str, Any], prompt_token_ids: list[int], guided_decoding: dict[str, Any] | None = None) -> None

components/src/dynamo/frontend/prepost.py#L46

Public methods

init

1__init__(request_for_sampling: ChatCompletionRequest, tool_parser: ToolParser | None, chat_template_kwargs: dict[str, Any], engine_prompt: dict[str, Any], prompt_token_ids: list[int], guided_decoding: dict[str, Any] | None = None) -> None

No summary available.

source

No summary available.

1from dynamo.frontend.sglang_processor import SglangEngineFactory
1SglangEngineFactory(config: FrontendConfig, debug_perf: bool = False, tool_call_parser_name: str | None = None, reasoning_parser_name: str | None = None, chat_template: str | None = None)

components/src/dynamo/frontend/sglang_processor.py#L889

Public methods

init

1__init__(config: FrontendConfig, debug_perf: bool = False, tool_call_parser_name: str | None = None, reasoning_parser_name: str | None = None, chat_template: str | None = None)

No summary available.

source

chat_engine_factory

1chat_engine_factory(instance_id: ModelCardInstanceId, mdc: ModelDeploymentCard, routed_engine: RoutedEngine) -> PythonAsyncEngine

Called by Rust when a model is discovered.

source

Result of SGLang preprocessing.

1from dynamo.frontend.sglang_prepost import SglangPreprocessResult
1SglangPreprocessResult(prompt_token_ids: list[int], tool_call_parser: ToolCallParserType | None, reasoning_parser: ReasoningParser | None, guided_decoding: dict[str, Any] | None, request: dict[str, Any], force_reasoning: bool = False) -> None

components/src/dynamo/frontend/sglang_prepost.py#L43

Public methods

init

1__init__(prompt_token_ids: list[int], tool_call_parser: ToolCallParserType | None, reasoning_parser: ReasoningParser | None, guided_decoding: dict[str, Any] | None, request: dict[str, Any], force_reasoning: bool = False) -> None

No summary available.

source

Picklable return value from the SGLang preprocess worker.

1from dynamo.frontend.sglang_processor import SglangPreprocessWorkerResult
1SglangPreprocessWorkerResult(prompt_token_ids: list[int], dynamo_preproc: dict[str, Any], request: dict[str, Any], force_reasoning: bool = False, effective_reasoning_parser_name: str | None = None) -> None

components/src/dynamo/frontend/sglang_processor.py#L271

Public methods

init

1__init__(prompt_token_ids: list[int], dynamo_preproc: dict[str, Any], request: dict[str, Any], force_reasoning: bool = False, effective_reasoning_parser_name: str | None = None) -> None

No summary available.

source

No summary available.

1from dynamo.frontend.sglang_processor import SglangProcessor
1SglangProcessor(tokenizer, routed_engine: RoutedEngine, tool_call_parser_name: str | None, reasoning_parser_name: str | None, eos_token_ids: list[int] | None, debug_perf: bool = False, preprocess_pool: ProcessPoolExecutor | None = None, preprocess_workers: int = 0, stream_interval: int = 1, default_thinking_mode: str | None = None)

components/src/dynamo/frontend/sglang_processor.py#L460

Public methods

init

1__init__(tokenizer, routed_engine: RoutedEngine, tool_call_parser_name: str | None, reasoning_parser_name: str | None, eos_token_ids: list[int] | None, debug_perf: bool = False, preprocess_pool: ProcessPoolExecutor | None = None, preprocess_workers: int = 0, stream_interval: int = 1, default_thinking_mode: str | None = None)

No summary available.

source

generator

1generator(request: dict[str, Any], context: Any | None = None) -> AsyncGenerator[dict[str, Any], None]

Main entry point: preprocess, route, post-process a chat request.

source

Streaming post-processor using SGLang parsers and HF tokenizer detokenization.

1from dynamo.frontend.sglang_prepost import SglangStreamingPostProcessor
1SglangStreamingPostProcessor(*, tokenizer, tool_call_parser: ToolCallParserType | None, reasoning_parser: ReasoningParser | None, history_tool_calls_count: int = 0, sglang_tools: list[SglangTool] | None = None, tool_call_parser_name: str | None = None, eos_token_ids: list[int] | None = None, prompt_token_ids: list[int] | None = None) -> None

Handles:

  • Incremental detokenization across tokenizer-safe boundaries
  • Reasoning content extraction via SGLang ReasoningParser
  • Tool call parsing via SGLang FunctionCallParser or JsonArrayParser

components/src/dynamo/frontend/sglang_prepost.py#L957

Public methods

init

1__init__(*, tokenizer, tool_call_parser: ToolCallParserType | None, reasoning_parser: ReasoningParser | None, history_tool_calls_count: int = 0, sglang_tools: list[SglangTool] | None = None, tool_call_parser_name: str | None = None, eos_token_ids: list[int] | None = None, prompt_token_ids: list[int] | None = None) -> None

No summary available.

source

process_output

1process_output(engine_response: dict[str, Any]) -> dict[str, Any] | None

Process a single engine response chunk into an OpenAI SSE choice dict.

Parameters

engine_response
dict[str, Any]

Dict with token_ids and optional finish_reason.

Returns

  • dict[str, Any] | None — OpenAI choice dict or None if nothing to emit yet.

source

No summary available.

1from dynamo.frontend.prepost import StreamingPostProcessor
1StreamingPostProcessor(*, tokenizer: TokenizerLike, request_for_sampling: ChatCompletionRequest, sampling_params: SamplingParams, prompt_token_ids: Sequence[int], tool_parser: ToolParser | None, reasoning_parser_class: type[ReasoningParser] | None, chat_template_kwargs: dict[str, Any], stream_response: bool = True) -> None

components/src/dynamo/frontend/prepost.py#L628

Public methods

init

1__init__(*, tokenizer: TokenizerLike, request_for_sampling: ChatCompletionRequest, sampling_params: SamplingParams, prompt_token_ids: Sequence[int], tool_parser: ToolParser | None, reasoning_parser_class: type[ReasoningParser] | None, chat_template_kwargs: dict[str, Any], stream_response: bool = True) -> None

No summary available.

source

process_output

1process_output(output: Any) -> dict[str, Any] | None

No summary available.

source

No summary available.

1from dynamo.frontend.vllm_processor import VllmProcessor
1VllmProcessor(tokenizer: TokenizerLike, input_processor: InputProcessor, output_processor: OutputProcessor, tool_parser_class: type[ToolParser] | None, reasoning_parser_class: type[ReasoningParser] | None, routed_engine: RoutedEngine, block_size: int = 16, enable_auto_tool_choice: bool = False, default_chat_template_kwargs: dict[str, Any] | None = None, default_thinking_mode: str | None = None, structural_tag_mode: str = 'off', structural_tag_scope: str = 'auto', structural_tag_schema: str = 'auto')

components/src/dynamo/frontend/vllm_processor.py#L268

Public methods

init

1__init__(tokenizer: TokenizerLike, input_processor: InputProcessor, output_processor: OutputProcessor, tool_parser_class: type[ToolParser] | None, reasoning_parser_class: type[ReasoningParser] | None, routed_engine: RoutedEngine, block_size: int = 16, enable_auto_tool_choice: bool = False, default_chat_template_kwargs: dict[str, Any] | None = None, default_thinking_mode: str | None = None, structural_tag_mode: str = 'off', structural_tag_scope: str = 'auto', structural_tag_schema: str = 'auto')

No summary available.

source

generator

1generator(request: dict[str, Any], context: Any | None = None) -> AsyncGenerator[dict[str, Any], None]

Run a single request through the engine. Does pre and post processing on this machine, delegates model inference to a backend using the router.

source

Merge deployment thinking default unless the request already controls it.

1from dynamo.frontend.thinking import apply_default_thinking_mode_to_template_kwargs
1apply_default_thinking_mode_to_template_kwargs(chat_template_kwargs: dict[str, Any], default_thinking_mode: str | None, *, request_has_root_thinking: bool = False) -> dict[str, Any]

components/src/dynamo/frontend/thinking.py#L33

Main async entry point for the Dynamo frontend.

1from dynamo.frontend.main import async_main
1async_main()

Initializes the distributed runtime, configures routing, and starts the HTTP server or interactive mode based on command-line arguments.

components/src/dynamo/frontend/main.py#L322

Build Dynamo guided decoding from OpenAI chat response_format.

1from dynamo.frontend.sglang_prepost import build_response_format_guided_decoding
1build_response_format_guided_decoding(request: dict[str, Any]) -> dict[str, Any] | None

components/src/dynamo/frontend/sglang_prepost.py#L639

Build tool-call guidance through vLLM’s configured tool parser.

1from dynamo.frontend.prepost import build_tool_call_guided_decoding
1build_tool_call_guided_decoding(request: ChatCompletionRequest, tool_parser: ToolParser | None, *, parser_guided_decoding: dict[str, Any] | None = None, structural_tag_mode: str = 'off', structural_tag_scope: str = 'auto', structural_tag_schema: str = 'auto') -> dict[str, Any] | None

components/src/dynamo/frontend/prepost.py#L207

Build native-SGLang-like tool call constraints for guided decoding.

1from dynamo.frontend.sglang_prepost import build_tool_call_guided_decoding
1build_tool_call_guided_decoding(request: dict[str, Any], *, tool_call_parser_name: str | None, sglang_tools: list[SglangTool] | None) -> dict[str, Any] | None

components/src/dynamo/frontend/sglang_prepost.py#L562

Convert OpenAI tool dicts to SGLang Tool objects.

1from dynamo.frontend.sglang_prepost import convert_tools
1convert_tools(tools: list[dict[str, Any]] | None) -> list[SglangTool] | None

components/src/dynamo/frontend/sglang_prepost.py#L196

Create tool call and reasoning parsers for a request.

1from dynamo.frontend.sglang_prepost import create_parsers
1create_parsers(request: dict[str, Any], *, tool_call_parser_name: str | None, reasoning_parser_name: str | None, sglang_tools: list[SglangTool] | None = None, force_reasoning: bool = False) -> tuple[ToolCallParserType | None, ReasoningParser | None]

Shared by both the single-process preprocessing path and the pool path (which must recreate non-picklable parsers in the main process).

If sglang_tools is provided, reuses them; otherwise converts from the request’s tools field.

For tool_choice="required" or a named function, uses JsonArrayParser (matching native SGLang) since guided decoding constrains the output to a JSON array. Otherwise uses the model-specific FunctionCallParser.

components/src/dynamo/frontend/sglang_prepost.py#L270

Return True if the chat template auto-opens a reasoning block.

1from dynamo.frontend.sglang_prepost import detect_force_reasoning_from_template
1detect_force_reasoning_from_template(chat_template: str | None) -> bool

Intended to be called once at processor startup with tokenizer.chat_template and cached on the processor.

components/src/dynamo/frontend/sglang_prepost.py#L79

Extract media and vLLM image processor-cache UUIDs from chat messages.

1from dynamo.frontend.utils import extract_mm_urls
1extract_mm_urls(messages: list[dict[str, Any]]) -> tuple[dict[str, list[dict[str, str]]] | None, dict[str, list[str | None]] | None]

URL-backed parts become Url variants. Image parts with no URL and an opaque uuid become UuidOnly variants for vLLM’s multimodal processor cache. Cache UUIDs on audio and video are rejected. Image UUID lists preserve slot order

({"image_url": [{"Url": "https://..."}, {"UuidOnly": "image-1"}]},
{"image_url": ["image-1", "image-1"]})

The UUID map is None when no user UUID is present. A media content part with neither a URL nor UUID is rejected instead of being silently dropped.

components/src/dynamo/frontend/utils.py#L100

Handle graceful shutdown of the distributed runtime.

1from dynamo.frontend.main import graceful_shutdown
1graceful_shutdown(runtime: DistributedRuntime) -> None

Parameters

runtime
DistributedRuntime

The DistributedRuntime instance to shut down.

components/src/dynamo/frontend/main.py#L482

Classify an invalid engine response and return an OpenAI-style error dict.

1from dynamo.frontend.utils import handle_engine_error
1handle_engine_error(engine_response: Any, request_id: str, logger: logging.Logger) -> dict[str, Any]

Called when engine_response is None or missing ‘token_ids’.

components/src/dynamo/frontend/utils.py#L184

Load trusted frontend route extensions.

1from dynamo.frontend.main import load_frontend_route_extensions
1load_frontend_route_extensions(extension_names: list[str]) -> list[FrontendRoute]

Each value is either a name registered under the dynamo.frontend.routes entry-point group (preferred) or a direct module:function path.

components/src/dynamo/frontend/main.py#L217

Entry point for the Dynamo frontend CLI.

1from dynamo.frontend.main import main
1main() -> None

components/src/dynamo/frontend/main.py#L491

Build an OpenAI-style error dict, guarding against None/missing message.

1from dynamo.frontend.utils import make_backend_error
1make_backend_error(engine_response: dict[str, Any]) -> dict[str, Any]

components/src/dynamo/frontend/utils.py#L162

Build an OpenAI-style internal error dict with request-specific fallback.

1from dynamo.frontend.utils import make_internal_error
1make_internal_error(request_id: str, detail: str | None = None) -> dict[str, Any]

components/src/dynamo/frontend/utils.py#L173

No summary available.

1from dynamo.frontend.vllm_processor import map_finish_reason
1map_finish_reason(raw_reason: str | None) -> FinishReason | None

components/src/dynamo/frontend/vllm_processor.py#L64

Return whether a request opted into a response nvext field.

1from dynamo.frontend.utils import nvext_extra_field_requested
1nvext_extra_field_requested(request: dict[str, Any], field: str) -> bool

components/src/dynamo/frontend/utils.py#L69

Parse command-line arguments for the Dynamo frontend.

1from dynamo.frontend.main import parse_args
1parse_args() -> tuple[FrontendConfig, Optional[Namespace], Optional[Namespace]]

Returns

  • tuple[FrontendConfig, Optional[Namespace], Optional[Namespace]] — Tuple of (FrontendConfig, vllm_flags, sglang_flags).

components/src/dynamo/frontend/main.py#L245

No summary available.

1from dynamo.frontend.prepost import preprocess_chat_request
1preprocess_chat_request(request: dict[str, Any] | ChatCompletionRequest, *, tokenizer: TokenizerLike, renderer: _Renderer, tool_parser_class: type[ToolParser] | None, exclude_tools_when_tool_choice_none: bool = True, enable_auto_tool_choice: bool = False, default_chat_template_kwargs: dict[str, Any] | None = None, default_thinking_mode: str | None = None, structural_tag_mode: str = 'off', structural_tag_scope: str = 'auto', structural_tag_schema: str = 'auto') -> PreprocessResult

components/src/dynamo/frontend/prepost.py#L522

Preprocess a chat request using SGLang tokenizer and parser APIs.

1from dynamo.frontend.sglang_prepost import preprocess_chat_request
1preprocess_chat_request(request: dict[str, Any], *, tokenizer, tool_call_parser_name: str | None, reasoning_parser_name: str | None, exclude_tools_when_tool_choice_none: bool = True, template_force_reasoning: bool = False, default_thinking_mode: str | None = None) -> SglangPreprocessResult

template_force_reasoning is the static per-server flag derived from the chat template (see detect_force_reasoning_from_template); the effective per-request value combines it with the configured parser and request-level thinking controls.

Synchronous — suitable for both main-process and worker-process execution.

components/src/dynamo/frontend/sglang_prepost.py#L724

Generate a random tool call ID in OpenAI format.

1from dynamo.frontend.utils import random_call_id
1random_call_id() -> str

components/src/dynamo/frontend/utils.py#L64

Generate a random 16-character hex UUID.

1from dynamo.frontend.utils import random_uuid
1random_uuid() -> str

components/src/dynamo/frontend/utils.py#L59

Read a Jinja chat template using backend-specific file semantics.

1from dynamo.frontend.utils import read_jinja_chat_template
1read_jinja_chat_template(template_path: str, *, backend: ChatProcessorBackend) -> str

components/src/dynamo/frontend/utils.py#L18

Return a chat template stored beside the model, or None.

1from dynamo.frontend.utils import resolve_chat_template
1resolve_chat_template(source_path: str, *, backend: ChatProcessorBackend = 'vllm') -> str | None

Covers models (e.g. Qwen3-Omni) whose template lives in chat_template.json or chat_template.jinja rather than tokenizer_config.json, which the HF tokenizer does not merge. The backend selects native .jinja file semantics.

components/src/dynamo/frontend/utils.py#L33

Resolve the effective force_reasoning flag for a single request.

1from dynamo.frontend.sglang_prepost import resolve_request_force_reasoning
1resolve_request_force_reasoning(request: dict[str, Any], reasoning_parser_name: str | None, template_default: bool) -> bool

Mirrors sglang.srt.entrypoints.openai.serving_chat._get_reasoning_from_request combined with template_manager.force_reasoning:

  • opt-out families (glm45/qwen3/kimi_k2/kimi_k3/…): on by default, chat_template_kwargs.enable_thinking=False (or thinking=False for Kimi) disables it.
  • MiniMax-M3 defaults to adaptive, but SGLang still enables the reasoning parser unless chat_template_kwargs.thinking_mode is explicitly "disabled".
  • Mistral is enabled only when reasoning_effort is present and not "none".
  • opt-in families (deepseek-v3/gemma4): off by default, enabled by chat_template_kwargs.{thinking,enable_thinking}=True.
  • anything else: follow the statically-detected template default.

components/src/dynamo/frontend/sglang_prepost.py#L122

Read deployment-level default thinking mode from model runtime metadata.

1from dynamo.frontend.thinking import runtime_default_thinking_mode
1runtime_default_thinking_mode(runtime_config: dict[str, Any] | None) -> str | None

components/src/dynamo/frontend/thinking.py#L20

When using vllm pre and post processor, create the EngineFactory that creates the engines that run requests.

1from dynamo.frontend.main import setup_engine_factory
1setup_engine_factory(config: FrontendConfig, vllm_flags: Namespace) -> EngineFactory

components/src/dynamo/frontend/main.py#L100

When using sglang pre and post processor, create the SglangEngineFactory that creates the engines that run requests.

1from dynamo.frontend.main import setup_sglang_engine_factory
1setup_sglang_engine_factory(config: FrontendConfig, sglang_flags: Optional[Namespace] = None)

components/src/dynamo/frontend/main.py#L113

Validate that model-name is a non-empty string.

1from dynamo.frontend.frontend_args import validate_model_name
1validate_model_name(value: str) -> str

components/src/dynamo/frontend/frontend_args.py#L35

Validate that model-path is a valid directory on disk.

1from dynamo.frontend.frontend_args import validate_model_path
1validate_model_path(value: str) -> str

components/src/dynamo/frontend/frontend_args.py#L44

Dummy task to ensure a ProcessPoolExecutor worker is fully initialized.

1from dynamo.frontend.utils import worker_warmup
1worker_warmup() -> bool

components/src/dynamo/frontend/utils.py#L78