Apply user-supplied engine_args (JSON object) onto an AsyncEngineArgs. Returns a new AsyncEngineArgs with the typed fields preserved and the user's overrides layered on top. Uses ``dataclasses.replace`` so vLLM's ``__post_init__`` re-runs and auto-converts dict-valued fields
(self, engine_args, engine_args_json)
| 110 | return opts |
| 111 | |
| 112 | def _apply_engine_args(self, engine_args, engine_args_json): |
| 113 | """Apply user-supplied engine_args (JSON object) onto an AsyncEngineArgs. |
| 114 | |
| 115 | Returns a new AsyncEngineArgs with the typed fields preserved and the |
| 116 | user's overrides layered on top. Uses ``dataclasses.replace`` so vLLM's |
| 117 | ``__post_init__`` re-runs and auto-converts dict-valued fields like |
| 118 | ``compilation_config`` / ``attention_config`` into their dataclass form. |
| 119 | ``speculative_config`` and ``kv_transfer_config`` are accepted as dicts |
| 120 | directly (vLLM converts them at engine init). |
| 121 | |
| 122 | Unknown keys raise ValueError with the closest valid field as a hint. |
| 123 | """ |
| 124 | if not engine_args_json: |
| 125 | return engine_args |
| 126 | try: |
| 127 | extra = json.loads(engine_args_json) |
| 128 | except json.JSONDecodeError as e: |
| 129 | raise ValueError(f"engine_args is not valid JSON: {e}") from e |
| 130 | if not isinstance(extra, dict): |
| 131 | raise ValueError( |
| 132 | f"engine_args must be a JSON object, got {type(extra).__name__}" |
| 133 | ) |
| 134 | valid = {f.name for f in dataclasses.fields(type(engine_args))} |
| 135 | for key in extra: |
| 136 | if key not in valid: |
| 137 | suggestion = difflib.get_close_matches(key, valid, n=1) |
| 138 | hint = f" did you mean {suggestion[0]!r}?" if suggestion else "" |
| 139 | raise ValueError(f"unknown engine_args key {key!r}.{hint}") |
| 140 | return dataclasses.replace(engine_args, **extra) |
| 141 | |
| 142 | def _messages_to_dicts(self, messages): |
| 143 | """Convert proto Messages to list of dicts suitable for apply_chat_template().""" |