diff --git a/src/timmy/cli.py b/src/timmy/cli.py index db25def..04c8a1c 100644 --- a/src/timmy/cli.py +++ b/src/timmy/cli.py @@ -179,28 +179,44 @@ def interview( typer.echo("Initializing Timmy for interview...\n") - # Force agent creation by calling chat once with a warm-up prompt + # Use a single persistent event loop for the entire interview. + # Calling asyncio.run() per question kills the loop between calls, + # orphaning MCP stdio transports and causing "Event loop is closed." + loop = asyncio.new_event_loop() + asyncio.set_event_loop(loop) + try: - asyncio.run( - chat("Hello, Timmy. We're about to start your interview.", session_id="interview") + # Force agent creation by calling chat once with a warm-up prompt + try: + loop.run_until_complete( + chat("Hello, Timmy. We're about to start your interview.", session_id="interview") + ) + except Exception as exc: + typer.echo(f"Warning: Initialization issue — {exc}", err=True) + + def _on_answer(entry: InterviewEntry) -> None: + typer.echo(f"[{entry.category}]") + typer.echo(f" Q: {entry.question}") + typer.echo(f" A: {entry.answer}") + typer.echo() + + typer.echo("Starting interview...\n") + transcript = run_interview( + chat_fn=lambda msg: loop.run_until_complete(chat(msg, session_id="interview")), + on_answer=_on_answer, ) - except Exception as exc: - typer.echo(f"Warning: Initialization issue — {exc}", err=True) - def _on_answer(entry: InterviewEntry) -> None: - typer.echo(f"[{entry.category}]") - typer.echo(f" Q: {entry.question}") - typer.echo(f" A: {entry.answer}") - typer.echo() + # Print full transcript at the end + typer.echo("\n" + format_transcript(transcript)) + finally: + # Clean shutdown: close MCP sessions, then the loop + try: + from timmy.mcp_tools import close_mcp_sessions - typer.echo("Starting interview...\n") - transcript = run_interview( - chat_fn=lambda msg: asyncio.run(chat(msg, session_id="interview")), - on_answer=_on_answer, - ) - - # Print full transcript at the end - typer.echo("\n" + format_transcript(transcript)) + loop.run_until_complete(close_mcp_sessions()) + except Exception: + pass + loop.close() @app.command()