兼容 SuperAgent SSE 结果解析

This commit is contained in:
andy
2026-07-11 12:35:09 +08:00
parent 1046e4ef74
commit c5e72078e5
2 changed files with 247 additions and 17 deletions

View File

@@ -1,6 +1,7 @@
package cn.nianxx.thhotel.integrations.ai.superagent.service.impl;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatThrownBy;
import cn.nianxx.thhotel.integrations.ai.superagent.common.result.SuperAgentOpenApiResult;
import org.junit.jupiter.api.Test;
@@ -38,4 +39,129 @@ class SuperAgentOpenApiSseParserTest {
assertThat(result.totalTokens()).isEqualTo(18);
assertThat(result.eventTypes()).containsExactly("metadata", "messages", "values", "end");
}
@Test
void shouldExtractFinalAiAnswerFromMessagesEventWhenStopReasonPresent() {
String sse = """
event: metadata
data: {"run_id":"run-debug-002","resolved_profile_id":"profile-debug"}
event: messages
data: {"type":"ai","content":"{\\"ai_task_results\\":[{\\"task_type\\":\\"Update Booking\\"}]}","response_metadata":{"finish_reason":"stop","model_name":"debug-model-from-message"},"usage_metadata":{"input_tokens":21,"output_tokens":13,"total_tokens":34}}
event: end
data: {}
""";
SuperAgentOpenApiResult result = parser.parse("session-debug-002", sse);
assertThat(result.runId()).isEqualTo("run-debug-002");
assertThat(result.rawAnswer()).isEqualTo("{\"ai_task_results\":[{\"task_type\":\"Update Booking\"}]}");
assertThat(result.modelName()).isEqualTo("debug-model-from-message");
assertThat(result.inputTokens()).isEqualTo(21);
assertThat(result.outputTokens()).isEqualTo(13);
assertThat(result.totalTokens()).isEqualTo(34);
assertThat(result.eventTypes()).containsExactly("metadata", "messages", "end");
}
@Test
void shouldFallbackToLastAiMessageWhenStreamEndedWithoutStopReason() {
String sse = """
event: messages
data: {"type":"ai","content":"partial answer"}
event: messages
data: {"type":"ai","content":"{\\"ai_task_results\\":[{\\"task_type\\":\\"Rooming List\\"}]}","response_metadata":{"model_name":"debug-model-fallback"}}
event: end
data: {}
""";
SuperAgentOpenApiResult result = parser.parse("session-debug-003", sse);
assertThat(result.rawAnswer()).isEqualTo("{\"ai_task_results\":[{\"task_type\":\"Rooming List\"}]}");
assertThat(result.modelName()).isEqualTo("debug-model-fallback");
}
@Test
void shouldFailWhenEndEventMissingEvenIfAiContentExists() {
String sse = """
event: messages
data: {"type":"ai","content":"{\\"ai_task_results\\":[]}","response_metadata":{"finish_reason":"stop"}}
""";
assertThatThrownBy(() -> parser.parse("session-debug-004", sse))
.isInstanceOf(SuperAgentOpenApiException.class)
.hasMessageContaining("SuperAgent SSE 未收到结束事件。");
}
@Test
void shouldFailWhenStreamEndedWithoutAiContent() {
String sse = """
event: metadata
data: {"run_id":"run-debug-005"}
event: values
data: {"messages":[{"type":"human","content":"input"}]}
event: end
data: {}
""";
assertThatThrownBy(() -> parser.parse("session-debug-005", sse))
.isInstanceOf(SuperAgentOpenApiException.class)
.hasMessageContaining("SuperAgent SSE 未找到最终 AI 回答。");
}
@Test
void shouldNotUseMessagesAfterEndAsFinalAnswer() {
String sse = """
event: end
data: {}
event: messages
data: {"type":"ai","content":"{\\"ai_task_results\\":[]}","response_metadata":{"finish_reason":"stop"}}
""";
assertThatThrownBy(() -> parser.parse("session-debug-006", sse))
.isInstanceOf(SuperAgentOpenApiException.class)
.hasMessageContaining("SuperAgent SSE 未找到最终 AI 回答。");
}
@Test
void shouldAcceptEndEventWithoutData() {
String sse = """
event: messages
data: {"type":"ai","content":"{\\"ai_task_results\\":[{\\"task_type\\":\\"Voucher Payment\\"}]}","response_metadata":{"finish_reason":"stop"}}
event: end
""";
SuperAgentOpenApiResult result = parser.parse("session-debug-007", sse);
assertThat(result.rawAnswer()).isEqualTo("{\"ai_task_results\":[{\"task_type\":\"Voucher Payment\"}]}");
assertThat(result.eventTypes()).containsExactly("messages", "end");
}
@Test
void shouldSerializeObjectContentAsFinalAnswer() {
String sse = """
event: messages
data: {"type":"ai","content":{"ai_task_results":[{"task_type":"Cancel Booking"}]},"response_metadata":{"finish_reason":"stop"}}
event: end
data: {}
""";
SuperAgentOpenApiResult result = parser.parse("session-debug-008", sse);
assertThat(result.rawAnswer()).isEqualTo("{\"ai_task_results\":[{\"task_type\":\"Cancel Booking\"}]}");
}
}