feat: 添加 Analytics 分析功能(行为追踪、错误码、协议更新)

This commit is contained in:
qzl
2026-04-02 11:52:23 +08:00
parent b101826de5
commit 7b6dbe72c3
24 changed files with 682 additions and 52 deletions
@@ -385,4 +385,86 @@ void main() {
expect(bloc.state.currentStage, isNull);
},
);
test('chat completed analytics triggers once only on RUN_FINISHED', () async {
final service = _FakeAgUiService();
var completedCalls = 0;
String? lastConversationId;
int? lastMessageCount;
int? lastResponseTimeMs;
final bloc = ChatBloc(
service: service,
chatApi: _NoopChatApi(),
onChatCompleted:
({
required String conversationId,
required int messageCount,
required int responseTimeMs,
}) {
completedCalls += 1;
lastConversationId = conversationId;
lastMessageCount = messageCount;
lastResponseTimeMs = responseTimeMs;
},
);
service.emitEventForTest(
RunStartedEvent(threadId: 'thread-1', runId: 'run-1'),
);
service.emitEventForTest(
TextMessageEndEvent(
messageId: 'msg-1',
answer: 'hello',
role: 'assistant',
status: 'success',
uiSchema: null,
),
);
expect(completedCalls, 0);
service.emitEventForTest(
RunFinishedEvent(threadId: 'thread-1', runId: 'run-1'),
);
service.emitEventForTest(
RunFinishedEvent(threadId: 'thread-1', runId: 'run-1'),
);
expect(completedCalls, 1);
expect(lastConversationId, 'thread-1');
expect(lastMessageCount, 1);
expect(lastResponseTimeMs, isNotNull);
expect(lastResponseTimeMs, greaterThanOrEqualTo(0));
bloc.close();
});
test('chat completed analytics does not trigger on RUN_ERROR', () async {
final service = _FakeAgUiService();
var completedCalls = 0;
final bloc = ChatBloc(
service: service,
chatApi: _NoopChatApi(),
onChatCompleted:
({
required String conversationId,
required int messageCount,
required int responseTimeMs,
}) {
completedCalls += 1;
},
);
service.emitEventForTest(
RunStartedEvent(threadId: 'thread-1', runId: 'run-1'),
);
service.emitEventForTest(
RunErrorEvent(message: 'run failed', code: 'RUN_FAILED'),
);
expect(completedCalls, 0);
bloc.close();
});
}