(query: str)
| 648 | exit_code = 0 |
| 649 | |
| 650 | async def execute_query(query: str): |
| 651 | nonlocal exit_code |
| 652 | |
| 653 | # Auto-resume magic: Check if the last event in the session indicates an |
| 654 | # active interrupt (Human-In-The-Loop suspension). If so, we automatically |
| 655 | # map the user's text query to the required function response instead of |
| 656 | # treating it as a new user message. |
| 657 | # Find the last event with active interrupts |
| 658 | interrupt_event = None |
| 659 | for e in reversed(session.events): |
| 660 | if e.long_running_tool_ids: |
| 661 | interrupt_event = e |
| 662 | break |
| 663 | |
| 664 | if interrupt_event: |
| 665 | # Assume the first active interrupt is the one we want to answer |
| 666 | interrupt_id = list(interrupt_event.long_running_tool_ids)[0] |
| 667 | if not jsonl: |
| 668 | click.secho( |
| 669 | f'Auto-resuming interrupt {interrupt_id} with input: {query}', |
| 670 | fg='cyan', |
| 671 | err=True, |
| 672 | ) |
| 673 | |
| 674 | # Construct a FunctionResponse pointing back to the interrupt ID. |
| 675 | # We check the synthetic function name to handle different interrupt types. |
| 676 | # TODO: We still need to handle 'adk_request_credential' (auth). |
| 677 | # TODO: Support batch HITL or interactive selection when multiple |
| 678 | # interrupts are active. |
| 679 | fc = next( |
| 680 | ( |
| 681 | c |
| 682 | for c in interrupt_event.get_function_calls() |
| 683 | if c.id == interrupt_id |
| 684 | ), |
| 685 | None, |
| 686 | ) |
| 687 | |
| 688 | if fc and fc.name == 'adk_request_confirmation': |
| 689 | # Try to parse as JSON to support passing custom payload or explicit confirmed flag. |
| 690 | try: |
| 691 | parsed = json.loads(query) |
| 692 | if isinstance(parsed, dict): |
| 693 | response = parsed |
| 694 | else: |
| 695 | response = {'confirmed': _is_positive_response(query)} |
| 696 | except (json.JSONDecodeError, ValueError): |
| 697 | response = {'confirmed': _is_positive_response(query)} |
| 698 | |
| 699 | content = types.Content( |
| 700 | role='user', |
| 701 | parts=[ |
| 702 | types.Part( |
| 703 | function_response=types.FunctionResponse( |
| 704 | id=interrupt_id, |
| 705 | name='adk_request_confirmation', |
| 706 | response=response, |
| 707 | ) |
no test coverage detected