verl 0.7.x embedded vLLM server cannot load custom tool parser plugins (tool_parser_plugin import step skipped)

Author: zzzhang1127Created Sep 11, 2026Updated Sep 14, 2026

Summary

On the verl 0.7.x/0.8.x line that Agent Lightning pins, a custom vLLM tool-call parser plugin (--tool-parser-plugin / config tool_parser_plugin) can never be used with the embedded vLLM OpenAI server: verl's custom server entrypoint skips the plugin-import step that vllm serve performs, so the server dies at startup with:

ValueError: --enable-auto-tool-choice requires tool_parser:'<name>' which has not been registered

This matters for agent RL on models whose tool-call format has no built-in vLLM parser (in our case a MiniCPM-family model) — exactly the population Agent Lightning serves.

Root cause

  • vllm serve's entrypoint (vllm/entrypoints/openai/api_server.py, run_server) imports the plugin before building the app: if args.tool_parser_plugin: ToolParserManager.import_tool_parser(args.tool_parser_plugin).
  • verl 0.7.x's vLLMHttpServer.run_server (https://github.com/volcengine/verl/blob/v0.7.1/verl/workers/rollout/vllm_rollout/vllm_async_server.py#L441) builds the engine and app itself and never performs that import, while still honoring --tool-call-parser validation in init_app_state — so the parser name from the plugin cannot resolve.
  • verl upstream is not a viable venue: main removed server-side tool-parsing args entirely (tool parsing is expected client-side in AgentLoop; see volcengine/verl#6560 rejected and volcengine/verl#6844 closed), and 0.7.x is a frozen release line.

Fix we run in production

A 4-line patch at the top of verl's run_server (applied to site-packages):

python
if getattr(args, "tool_parser_plugin", None):
    from vllm.entrypoints.openai.tool_parsers import ToolParserManager
    ToolParserManager.import_tool_parser(args.tool_parser_plugin)

With this, actor_rollout_ref.rollout.multi_turn.tool_config-style configs with a custom parser plugin work end-to-end (running in our GRPO training since 09-08).

Proposal

This fits the same pattern as #589 / PR #590: a runtime shim in agentlightning/verl/vllm_compat.py that wraps vLLMHttpServer.run_server to perform the plugin import before delegating (strict no-op when no plugin is configured or the attribute doesn't exist). I'm happy to submit that PR — it builds on the compat module introduced in #590, so I'd stack it once #590 has a verdict.

Source: microsoft/agent-lightning