[Refactor][OutputProcessor 2/8]: OmniRequestOutput should inherit RequestOutput and no nested wrap-up (#5146)

Signed-off-by: Boao Shi <aoibosh@connect.hku.hk>
Signed-off-by: bowieshi <aoibosh@connect.hku.hk>
Signed-off-by: princepride <wangzhipeng628@gmail.com>
Signed-off-by: R2-Y <ruiruyang2@gmail.com>
Signed-off-by: amy-why-3459 <wuhaiyan17@huawei.com>
Signed-off-by: Shi Boao Bowie <aoibosh@connect.hku.hk>
Co-authored-by: 汪志鹏 <wangzhipeng628@gmail.com>
Co-authored-by: ruirui(rein) yang <73573651+R2-Y@users.noreply.github.com>
Co-authored-by: amy-why-3459 <wuhaiyan17@huawei.com>
Co-authored-by: Gao Han <hgaoaf@connect.ust.hk>
Co-authored-by: Hongsheng Liu <liuhongsheng4@huawei.com>
This commit is contained in:
authored and GitHub committed 2026-08-12 22:58:23 +08:00
1 parent 38a2500bdf
commit fcf1085395
89 files changed
+944 -639

No files matched your search

@@ -2156,12 +2156,12 @@ def test_direct_listen_decision_survives_inner_completion_metadata():
)
assert decision is not None
output = attach_duplex_output_decision(
OmniRequestOutput(
OmniRequestOutput.from_stage_output(
inner_output,
request_id="duplex-direct-listen",
finished=True,
stage_id=0,
final_output_type=decision.final_output_type,
request_output=inner_output,
metrics={
"stage_metrics": {
"0": {
@@ -3049,12 +3049,12 @@ async def test_minicpmo_auto_response_listen_without_response_does_not_defer_com
)
assert decision is not None
listen_output = attach_duplex_output_decision(
OmniRequestOutput(
OmniRequestOutput.from_stage_output(
inner_output,
request_id=request_id,
finished=True,
stage_id=0,
final_output_type=decision.final_output_type,
request_output=inner_output,
),
decision,
)
@@ -119,7 +119,6 @@ class MockGenerationResult:
def __init__(self, images):
self.images = images
self.request_output = SimpleNamespace(images=images)
self.stage_durations = {}
self.peak_memory_mb = 0.0
@@ -137,10 +136,7 @@ class MockStageResult:
outputs = [SimpleNamespace(text=text, index=0)]
else:
outputs = []
self.request_output = SimpleNamespace(
outputs=outputs,
images=self.images,
)
self.outputs = outputs
self.stage_durations = {}
self.peak_memory_mb = 0.0
@@ -2080,22 +2076,20 @@ def test_extract_images_from_result():
assert all(isinstance(img, Image.Image) for img in images)
assert all(img.size == (64, 64) for img in images)
# Test dict path: result.request_output["images"]
# Test result with "images" attribute set in __init__
class DictRequestOutput:
def __init__(self):
self.request_output = {"images": [np.random.randint(0, 255, (64, 64, 3), dtype=np.uint8)]}
self.images = [np.random.randint(0, 255, (64, 64, 3), dtype=np.uint8)]
result = DictRequestOutput()
images = _extract_images_from_result(result)
assert len(images) == 1
assert isinstance(images[0], Image.Image)
# Test attribute path: result.request_output.images
# Test result with "images" attribute from an inner object
class AttrRequestOutput:
def __init__(self):
self.request_output = type(
"obj", (), {"images": [np.random.randint(0, 255, (32, 32, 3), dtype=np.uint8)]}
)()
self.images = [np.random.randint(0, 255, (32, 32, 3), dtype=np.uint8)]
result = AttrRequestOutput()
images = _extract_images_from_result(result)
@@ -180,10 +180,10 @@ def create_mock_audio_output_for_test(
audio_tensor = torch.sin(torch.linspace(0, 440 * 2 * torch.pi, num_samples))
mock_request_output = MockRequestOutput(request_id=request_id, audio_tensor=audio_tensor)
return OmniRequestOutput(
return OmniRequestOutput.from_stage_output(
mock_request_output,
stage_id=0,
final_output_type="audio",
request_output=mock_request_output,
)
@@ -2292,10 +2292,10 @@ class TestStreamingResponse:
self.prompt_logprobs = None
self.kv_transfer_params = None
return OmniRequestOutput(
return OmniRequestOutput.from_stage_output(
MockRequestOutput(audio_tensor=chunk),
stage_id=0,
final_output_type="audio",
request_output=MockRequestOutput(audio_tensor=chunk),
finished=finished,
)
@@ -3441,10 +3441,10 @@ class TestWAVStreaming:
self.prompt_logprobs = None
self.kv_transfer_params = None
return OmniRequestOutput(
return OmniRequestOutput.from_stage_output(
MockRequestOutput(audio_tensor=chunk),
stage_id=0,
final_output_type="audio",
request_output=MockRequestOutput(audio_tensor=chunk),
finished=finished,
)
@@ -47,7 +47,7 @@ def _text_result(text: str) -> OmniRequestOutput:
output.text = text
request_output = RequestOutput()
request_output.outputs = [output]
return OmniRequestOutput(final_output_type="text", request_output=request_output)
return OmniRequestOutput.from_stage_output(request_output, final_output_type="text")
def _audio_result(audio_data: Any) -> OmniRequestOutput:
@@ -61,7 +61,7 @@ def _audio_result(audio_data: Any) -> OmniRequestOutput:
output.multimodal_output = {"audio": audio_data}
request_output = RequestOutput()
request_output.outputs = [output]
return OmniRequestOutput(final_output_type="audio", request_output=request_output)
return OmniRequestOutput.from_stage_output(request_output, final_output_type="audio")
class MockWebSocket: