[03-Developer] #260 round 2: AC-9 + AC-10 보강
QA round 1 환송 노트 (#260 카테고리 63 환송) 의 두 결함 수정. AC-9 — tool result 2KB 가드 runtime 연결 - chat_providers.dart userTurn: result.toJson() → encodeToolResult 통과 후 jsonDecode 한 Map 을 LlmChatSession.sendToolResult 로 전달. - encodeToolResult 가 더 이상 dead code 가 아니다. ADR-0005 / OQ-2 의 2KB hard cap 이 실 경로에서 적용됨. - 회귀: chat_session_controller_test.dart 신규 'AC-9 대용량 → cap' 케이스 — 인위 huge_dump tool 로 _truncated:true + _hint 검증. AC-10 — widget E2E 신규 - app/test/ui/chat_screen_test.dart 신규 (2 testWidgets): 1) add_habit tool call → ConfirmDialog '수행' → habits +1 + 모델 마무리. 2) ConfirmDialog '취소' → habits 무변화 + 'tool 취소됨' 라벨. - ProviderScope overrides: appDatabaseProvider / llmServiceProvider / bootstrapProvider / toolDepsProvider. 회귀 - 신규 3 (cap 1 + widget 2) → 151 → 154 passed (1 skip) - flutter analyze: clean Refs #260
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
import 'package:life_helper/ai/tools/tool_definition.dart';
|
||||
import 'package:life_helper/ai/tools/tool_dispatcher.dart';
|
||||
import 'package:life_helper/ai/tools/tool_envelope.dart';
|
||||
import 'package:life_helper/ai/tools/tool_registry.dart';
|
||||
@@ -163,6 +164,46 @@ void main() {
|
||||
expect(h.controller.state.error, isNull);
|
||||
});
|
||||
|
||||
testWidgets('대용량 tool result → 2KB cap 적용 (AC-9)', (tester) async {
|
||||
// 인위적으로 큰 payload 를 돌려주는 fake tool 로 dispatcher 를 구성.
|
||||
final hugePayload = {
|
||||
'items': List.generate(200, (i) => {'id': 'p_$i' * 5, 'text': 'x' * 20}),
|
||||
};
|
||||
final hugeTool = ToolDefinition(
|
||||
name: 'huge_dump',
|
||||
description: 'test-only huge result',
|
||||
parametersSchema: const {
|
||||
'type': 'object',
|
||||
'properties': {},
|
||||
'required': [],
|
||||
},
|
||||
handler: (_, _) async => ToolOk(hugePayload),
|
||||
);
|
||||
final ctx2 = await bootstrapToolDeps();
|
||||
addTearDown(() => ctx2.db.close());
|
||||
final mock = MockLlmService();
|
||||
await mock.load();
|
||||
final controller = ChatSessionController(
|
||||
llm: mock,
|
||||
dispatcher: ToolDispatcher(registry: ToolRegistry([hugeTool])),
|
||||
deps: ctx2.deps,
|
||||
tools: [hugeTool],
|
||||
);
|
||||
addTearDown(controller.dispose);
|
||||
final ctx = await mountContext(tester);
|
||||
|
||||
mock.enqueueChatEvents([const LlmFunctionCall('huge_dump', {})]);
|
||||
mock.enqueueChatEvents([const LlmTextChunk('처리 완료.')]);
|
||||
|
||||
await controller.userTurn('덤프', ctx);
|
||||
|
||||
final submitted = mock.lastChat!.toolResults.first.$2;
|
||||
expect(submitted['status'], 'ok');
|
||||
// encodeToolResult 가 cap 적용 → _truncated 마커 + _hint 메시지 포함.
|
||||
expect((submitted['data'] as Map)['_truncated'], true);
|
||||
expect((submitted['data'] as Map)['_hint'], contains('query_protocol'));
|
||||
});
|
||||
|
||||
testWidgets('tool result 가 다음 sendToolResult 로 전달', (tester) async {
|
||||
final h = await makeHarness();
|
||||
addTearDown(() {
|
||||
|
||||
Reference in New Issue
Block a user