From 50bdee27b48d91e80ffdbc93a60e236da682c092 Mon Sep 17 00:00:00 2001 From: DavidJBianco Date: Thu, 23 Apr 2026 08:57:56 -0400 Subject: [PATCH 1/2] Fix shared mutable previous_run defaults --- peak_assistant/able_assistant/__init__.py | 4 ++-- peak_assistant/data_assistant/__init__.py | 4 +++- peak_assistant/hypothesis_assistant/hypothesis_refiner_cli.py | 4 ++-- peak_assistant/planning_assistant/__init__.py | 4 +++- peak_assistant/research_assistant/__init__.py | 4 ++-- 5 files changed, 12 insertions(+), 8 deletions(-) diff --git a/peak_assistant/able_assistant/__init__.py b/peak_assistant/able_assistant/__init__.py index 741e7dd..21971bd 100644 --- a/peak_assistant/able_assistant/__init__.py +++ b/peak_assistant/able_assistant/__init__.py @@ -20,7 +20,7 @@ # # SPDX-License-Identifier: MIT -from typing import List +from typing import List, Optional from autogen_core.models import UserMessage, SystemMessage @@ -32,7 +32,7 @@ async def able_table( research_document: str, local_data_document: str, local_context: str, - previous_run: list[SystemMessage | UserMessage] = list(), + previous_run: Optional[list[SystemMessage | UserMessage]] = None, ) -> str: """ Generate a PEAK ABLE table based on the given hypothesis and research document. diff --git a/peak_assistant/data_assistant/__init__.py b/peak_assistant/data_assistant/__init__.py index d48333c..3b2df1b 100644 --- a/peak_assistant/data_assistant/__init__.py +++ b/peak_assistant/data_assistant/__init__.py @@ -20,6 +20,8 @@ # # SPDX-License-Identifier: MIT +from typing import Optional + from autogen_agentchat.base import TaskResult from autogen_agentchat.messages import TextMessage from autogen_agentchat.agents import AssistantAgent @@ -38,7 +40,7 @@ async def identify_data_sources( able_info: str, local_context: str, verbose: bool = False, - previous_run: list = list(), + previous_run: Optional[list] = None, mcp_server_group: str = "data_discovery", msg_preprocess_callback=None, msg_preprocess_kwargs=None, diff --git a/peak_assistant/hypothesis_assistant/hypothesis_refiner_cli.py b/peak_assistant/hypothesis_assistant/hypothesis_refiner_cli.py index b87e9bc..0a4b695 100755 --- a/peak_assistant/hypothesis_assistant/hypothesis_refiner_cli.py +++ b/peak_assistant/hypothesis_assistant/hypothesis_refiner_cli.py @@ -25,7 +25,7 @@ import os import sys import argparse -from typing import List +from typing import List, Optional from dotenv import load_dotenv import asyncio @@ -51,7 +51,7 @@ async def refiner( research_document: str, local_data_document: str, verbose: bool = False, - previous_run: list = list(), + previous_run: Optional[list] = None, msg_preprocess_callback=None, msg_preprocess_kwargs=None, msg_postprocess_callback=None, diff --git a/peak_assistant/planning_assistant/__init__.py b/peak_assistant/planning_assistant/__init__.py index a24dede..20380f4 100644 --- a/peak_assistant/planning_assistant/__init__.py +++ b/peak_assistant/planning_assistant/__init__.py @@ -20,6 +20,8 @@ # # SPDX-License-Identifier: MIT +from typing import Optional + from autogen_agentchat.messages import TextMessage from autogen_agentchat.agents import AssistantAgent from autogen_agentchat.teams import RoundRobinGroupChat @@ -38,7 +40,7 @@ async def plan_hunt( data_discovery: str, local_context: str, verbose: bool = False, - previous_run: list = list(), + previous_run: Optional[list] = None, msg_preprocess_callback=None, msg_preprocess_kwargs=None, msg_postprocess_callback=None, diff --git a/peak_assistant/research_assistant/__init__.py b/peak_assistant/research_assistant/__init__.py index bda32df..585d167 100644 --- a/peak_assistant/research_assistant/__init__.py +++ b/peak_assistant/research_assistant/__init__.py @@ -39,7 +39,7 @@ async def researcher( technique: str, local_context: str, verbose: bool = False, - previous_run: list = list(), + previous_run: Optional[list] = None, mcp_server_group_external: str = "research-external", user_id: Optional[str] = None, msg_preprocess_callback=None, @@ -397,7 +397,7 @@ async def local_data_searcher( local_context: str, research_document: str, verbose: bool = False, - previous_run: list = list(), + previous_run: Optional[list] = None, mcp_server_group_local_data: str = "local-data-search", user_id: Optional[str] = None, msg_preprocess_callback=None, From 281c380c3496d9bb1e3319bdf7c678d0793f46ba Mon Sep 17 00:00:00 2001 From: "David J. Bianco" Date: Thu, 23 Apr 2026 09:54:55 -0400 Subject: [PATCH 2/2] fix: remove double-wrap in refiner() and add clean CLI error boundary The inner try/except in refiner() was printing to stdout (garbling parseable output) and re-raising as a generic Exception, discarding the original type. Remove it so exceptions propagate with their native type and traceback intact. Add a single exception handler at the CLI boundary in main() that prints a concise message to stderr, shows the full traceback with --verbose, and exits with code 1. Supersedes PR #77. Co-Authored-By: Claude Sonnet 4.6 --- .../hypothesis_refiner_cli.py | 54 ++++++++++--------- 1 file changed, 28 insertions(+), 26 deletions(-) diff --git a/peak_assistant/hypothesis_assistant/hypothesis_refiner_cli.py b/peak_assistant/hypothesis_assistant/hypothesis_refiner_cli.py index 0a4b695..237c366 100755 --- a/peak_assistant/hypothesis_assistant/hypothesis_refiner_cli.py +++ b/peak_assistant/hypothesis_assistant/hypothesis_refiner_cli.py @@ -25,6 +25,7 @@ import os import sys import argparse +import traceback from typing import List, Optional from dotenv import load_dotenv import asyncio @@ -354,24 +355,19 @@ async def refiner( msgs=messages, **(msg_preprocess_kwargs or {}) ) - try: - # Run the team asynchronously - if verbose: - result = await Console(team.run_stream(task=messages), output_stats=True) - else: - result = await team.run(task=messages) + # Run the team asynchronously + if verbose: + result = await Console(team.run_stream(task=messages), output_stats=True) + else: + result = await team.run(task=messages) - # Postprocess the result - if msg_postprocess_callback: - result = msg_postprocess_callback( - result=result, **(msg_postprocess_kwargs or {}) - ) + # Postprocess the result + if msg_postprocess_callback: + result = msg_postprocess_callback( + result=result, **(msg_postprocess_kwargs or {}) + ) - # Access the content from the CreateResult object - return result # Use the correct attribute to access the generated content - except Exception as e: - print(f"Error while refining hypotheses: {e}") - raise Exception("An error occurred while refining the hypothesis.") from e + return result def main() -> None: @@ -497,17 +493,23 @@ def main() -> None: while True: # Run the hypothesizer asynchronously - response = asyncio.run( - refiner( - hypothesis=current_hypothesis, - local_context=local_context or "", - research_document=research_data, - local_data_document=local_data or "", - verbose=args.verbose, - previous_run=messages, - **debug_agents_opts, + try: + response = asyncio.run( + refiner( + hypothesis=current_hypothesis, + local_context=local_context or "", + research_document=research_data, + local_data_document=local_data or "", + verbose=args.verbose, + previous_run=messages, + **debug_agents_opts, + ) ) - ) + except Exception as e: + print(f"Error refining hypothesis: {e}", file=sys.stderr) + if args.verbose: + traceback.print_exc() + sys.exit(1) # Extract the refined hypothesis using the centralized extractor current_hypothesis, acceptance_msg = extract_refined_hypothesis(response, original_hypothesis=current_hypothesis)