$ uv run tools/flow.py test cases/lab03-limit.json -v ✔ before: POST http://localhost:8800/budget/reset · HTTP 200 · 0.0s · {"daily_usd": 1.0, "user_limit_per_min": 20, "max_question_chars": 500, "used_usd": 0, "remaining_usd": 1.0, "over": fal → request POST http://localhost:8800/budget/reset {} ← response HTTP 200 { "daily_usd": 1.0, "user_limit_per_min": 20, "max_question_chars": 500, "used_usd": 0, "remaining_usd": 1.0, "over": false } ✔ before: POST http://localhost:8800/usage-clear · HTTP 200 · 0.0s · {"cleared": 0} → request POST http://localhost:8800/usage-clear {} ← response HTTP 200 { "cleared": 0 } ✔ before: POST http://localhost:8800/budget · HTTP 200 · 0.0s · {"daily_usd": 1.0, "user_limit_per_min": 2, "max_question_chars": 500, "used_usd": 0, "remaining_usd": 1.0, "over": fals → request POST http://localhost:8800/budget { "user_limit_per_min": 2 } ← response HTTP 200 { "daily_usd": 1.0, "user_limit_per_min": 2, "max_question_chars": 500, "used_usd": 0, "remaining_usd": 1.0, "over": false } POST http://localhost:5678/webhook/my-cost · 4 case(s) × 1 ✔ 이준호 1번째 · 1.3s · 자동 답변 · 1 call · $0.000156 → request POST /webhook/my-cost { "question": "VPN 접속이 자꾸 끊겨요. 어떻게 하나요?", "user": "이준호" } ← response HTTP 200 { "route": "자동 답변", "answer": "VPN 접속 오류는 VPN 클라이언트를 최신 버전으로 업데이트하고, 인증서 만료 여부를 확인한 뒤 다시 접속하시기 바랍니다. 현재 접수된 관련 티켓은 없습니다. 추가 도움이 필요하시면 담당자가 도와드리겠습니다.", "sources": [ "FAQ-003" ], "llm_calls": 1, "usage": { "prompt_tokens": 165, "completion_tokens": 56, "by_step": { "answer": { "model": "gpt-4.1-mini", "prompt_tokens": 165, "completion_tokens": 56, "cost_usd": 0.0001556 } } }, "cost_usd": 0.0001556, "trimmed": false, "question_chars": 24, "recorded": true } ✔ 이준호 2번째 · 1.6s · 자동 답변 · 1 call · $0.000152 → request POST /webhook/my-cost { "question": "프린터 출력이 안 돼요", "user": "이준호" } ← response HTTP 200 { "route": "자동 답변", "answer": "프린터 전원과 네트워크 연결을 확인하고, 인쇄 대기열을 비운 뒤 다시 출력해 보시기 바랍니다. 현재 접수된 관련 문의는 없습니다. 추가 도움이 필요하시면 담당 직원이 도와드리겠습니다.", "sources": [ "FAQ-004" ], "llm_calls": 1, "usage": { "prompt_tokens": 164, "completion_tokens": 54, "by_step": { "answer": { "model": "gpt-4.1-mini", "prompt_tokens": 164, "completion_tokens": 54, "cost_usd": 0.000152 } } }, "cost_usd": 0.000152, "trimmed": false, "question_chars": 12, "recorded": true } ✘ 이준호 3번째 · 1분에 2번 넘음 · 1.3s · 자동 답변 · 1 call · $0.000156 · took 1.3s (expected at most 1s); status 200 (expected 429); route = 자동 답변 (expected 잠시 후); cost_usd = 0.0001556 (expected 0) → request POST /webhook/my-cost { "question": "VPN 접속이 자꾸 끊겨요. 어떻게 하나요?", "user": "이준호" } ← response HTTP 200 { "route": "자동 답변", "answer": "VPN 접속 오류는 VPN 클라이언트를 최신 버전으로 업데이트하고, 인증서 만료 여부를 확인한 뒤 다시 접속하시기 바랍니다. 현재 접수된 관련 티켓은 없습니다. 추가 도움이 필요하시면 담당자가 도와드리겠습니다.", "sources": [ "FAQ-003" ], "llm_calls": 1, "usage": { "prompt_tokens": 165, "completion_tokens": 56, "by_step": { "answer": { "model": "gpt-4.1-mini", "prompt_tokens": 165, "completion_tokens": 56, "cost_usd": 0.0001556 } } }, "cost_usd": 0.0001556, "trimmed": false, "question_chars": 24, "recorded": true } ✔ 다른 사람은 그대로 · 1.2s · 자동 답변 · 1 call · $0.000136 → request POST /webhook/my-cost { "question": "비밀번호를 잊어버렸어요. 재설정은 어떻게 하나요?", "user": "한지훈" } ← response HTTP 200 { "route": "자동 답변", "answer": "비밀번호 재설정은 사내 포털 로그인 화면의 '비밀번호 찾기'에서 휴대폰 인증 후 새 비밀번호를 설정하시면 됩니다. 추가 도움이 필요하시면 문의해 주세요.", "sources": [ "FAQ-001" ], "llm_calls": 1, "usage": { "prompt_tokens": 169, "completion_tokens": 43, "by_step": { "answer": { "model": "gpt-4.1-mini", "prompt_tokens": 169, "completion_tokens": 43, "cost_usd": 0.0001364 } } }, "cost_usd": 0.0001364, "trimmed": false, "question_chars": 27, "recorded": true } Passed 3/4 report: runs/lab03-limit-20261028-210727.json ✔ after: POST http://localhost:8800/budget/reset · HTTP 200 · 0.0s · {"daily_usd": 1.0, "user_limit_per_min": 20, "max_question_chars": 500, "used_usd": 0.0005996, "remaining_usd": 0.999400 → request POST http://localhost:8800/budget/reset {} ← response HTTP 200 { "daily_usd": 1.0, "user_limit_per_min": 20, "max_question_chars": 500, "used_usd": 0.0005996, "remaining_usd": 0.9994004, "over": false } ✔ after: POST http://localhost:8800/usage-clear · HTTP 200 · 0.0s · {"cleared": 4} → request POST http://localhost:8800/usage-clear {} ← response HTTP 200 { "cleared": 4 }