From 515504c604f99be39f02ef8884bce728b56eb261 Mon Sep 17 00:00:00 2001 From: Nicholas Tindle Date: Sun, 18 Jan 2026 23:53:23 -0600 Subject: [PATCH] fix(classic): resolve pyright type errors in original_autogpt - Change Agent class to use ActionProposal instead of OneShotAgentActionProposal to support multiple prompt strategy types - Widen display_thoughts parameter type from AssistantThoughts to ModelWithSummary - Fix speak attribute access in agent_protocol_server with hasattr check - Add type: ignore comments for intentional thoughts field overrides in strategies - Remove unused OneShotAgentActionProposal import Co-Authored-By: Claude Opus 4.5 --- .../test_prompt_strategies.py | 2 +- .../original_autogpt/autogpt/agents/agent.py | 52 +++++++++---------- .../agents/prompt_strategies/plan_execute.py | 2 +- .../agents/prompt_strategies/reflexion.py | 2 +- .../autogpt/agents/prompt_strategies/rewoo.py | 2 +- .../prompt_strategies/tree_of_thoughts.py | 2 +- .../autogpt/app/agent_protocol_server.py | 10 +++- .../autogpt/app/ui/protocol.py | 4 +- .../autogpt/app/ui/terminal/provider.py | 4 +- 9 files changed, 43 insertions(+), 37 deletions(-) diff --git a/classic/original_autogpt/agbenchmark_config/test_prompt_strategies.py b/classic/original_autogpt/agbenchmark_config/test_prompt_strategies.py index 6c97078852..105bc4e9ae 100644 --- a/classic/original_autogpt/agbenchmark_config/test_prompt_strategies.py +++ b/classic/original_autogpt/agbenchmark_config/test_prompt_strategies.py @@ -202,7 +202,7 @@ def run_benchmark( ) if result.returncode != 0: - # Non-zero exit code is normal - agbenchmark returns non-zero when tests fail + # Non-zero exit is normal - agbenchmark returns non-zero when tests fail print(f" Benchmark completed with code {result.returncode}") if result.stderr: print(f" stderr: {result.stderr[:500]}") diff --git a/classic/original_autogpt/autogpt/agents/agent.py b/classic/original_autogpt/autogpt/agents/agent.py index a0eeb18db1..e46bebaa09 100644 --- a/classic/original_autogpt/autogpt/agents/agent.py +++ b/classic/original_autogpt/autogpt/agents/agent.py @@ -51,6 +51,7 @@ from forge.llm.providers.utils import function_specs_from_commands from forge.models.action import ( ActionErrorResult, ActionInterruptedByHuman, + ActionProposal, ActionResult, ActionSuccessResult, ) @@ -64,12 +65,7 @@ from forge.utils.exceptions import ( ) from pydantic import Field -from autogpt.agents.prompt_strategies.plan_execute import PlanExecutePromptConfiguration - -from .prompt_strategies.one_shot import ( - OneShotAgentActionProposal, - OneShotAgentPromptStrategy, -) +from .prompt_strategies.one_shot import OneShotAgentPromptStrategy from .prompt_strategies.plan_execute import PlanExecutePromptStrategy from .prompt_strategies.reflexion import ReflexionPromptStrategy from .prompt_strategies.rewoo import ReWOOPromptStrategy @@ -90,15 +86,15 @@ class AgentSettings(BaseAgentSettings): default_factory=AgentConfiguration ) - history: EpisodicActionHistory[OneShotAgentActionProposal] = Field( - default_factory=EpisodicActionHistory[OneShotAgentActionProposal] + history: EpisodicActionHistory[ActionProposal] = Field( + default_factory=EpisodicActionHistory[ActionProposal] ) """(STATE) The action history of the agent.""" context: AgentContext = Field(default_factory=AgentContext) -class Agent(BaseAgent[OneShotAgentActionProposal], Configurable[AgentSettings]): +class Agent(BaseAgent[ActionProposal], Configurable[AgentSettings]): default_settings: ClassVar[AgentSettings] = AgentSettings( name="Agent", description=__doc__ if __doc__ else "", @@ -166,7 +162,7 @@ class Agent(BaseAgent[OneShotAgentActionProposal], Configurable[AgentSettings]): self.event_history = settings.history self.app_config = app_config - async def propose_action(self) -> OneShotAgentActionProposal: + async def propose_action(self) -> ActionProposal: """Proposes the next action to execute, based on the task and current state. Returns: @@ -214,11 +210,11 @@ class Agent(BaseAgent[OneShotAgentActionProposal], Configurable[AgentSettings]): async def complete_and_parse( self, prompt: ChatPrompt, exception: Optional[Exception] = None - ) -> OneShotAgentActionProposal: + ) -> ActionProposal: if exception: prompt.messages.append(ChatMessage.system(f"Error: {exception}")) - response: ChatModelResponse[OneShotAgentActionProposal] = ( + response: ChatModelResponse[ActionProposal] = ( await self.llm_provider.create_chat_completion( prompt.messages, model_name=self.llm.name, @@ -235,7 +231,7 @@ class Agent(BaseAgent[OneShotAgentActionProposal], Configurable[AgentSettings]): async def execute( self, - proposal: OneShotAgentActionProposal, + proposal: ActionProposal, user_feedback: str = "", ) -> ActionResult: tool = proposal.use_tool @@ -292,7 +288,7 @@ class Agent(BaseAgent[OneShotAgentActionProposal], Configurable[AgentSettings]): return result async def do_not_execute( - self, denied_proposal: OneShotAgentActionProposal, user_feedback: str + self, denied_proposal: ActionProposal, user_feedback: str ) -> ActionResult: result = ActionInterruptedByHuman(feedback=user_feedback) @@ -371,27 +367,29 @@ class Agent(BaseAgent[OneShotAgentActionProposal], Configurable[AgentSettings]): return ReWOOPromptStrategy(config, logger) elif strategy_name == "plan_execute": - config: PlanExecutePromptConfiguration = ( - PlanExecutePromptStrategy.default_configuration.model_copy(deep=True) + pe_config = PlanExecutePromptStrategy.default_configuration.model_copy( + deep=True ) - config.use_prefill = use_prefill - return PlanExecutePromptStrategy(config, logger) + pe_config.use_prefill = use_prefill + return PlanExecutePromptStrategy(pe_config, logger) elif strategy_name == "reflexion": - config = ReflexionPromptStrategy.default_configuration.model_copy(deep=True) - config.use_prefill = use_prefill - return ReflexionPromptStrategy(config, logger) + ref_config = ReflexionPromptStrategy.default_configuration.model_copy( + deep=True + ) + ref_config.use_prefill = use_prefill + return ReflexionPromptStrategy(ref_config, logger) elif strategy_name == "tree_of_thoughts": - config = TreeOfThoughtsPromptStrategy.default_configuration.model_copy( + tot_config = TreeOfThoughtsPromptStrategy.default_configuration.model_copy( deep=True ) - config.use_prefill = use_prefill - return TreeOfThoughtsPromptStrategy(config, logger) + tot_config.use_prefill = use_prefill + return TreeOfThoughtsPromptStrategy(tot_config, logger) else: # Default to one_shot - config = OneShotAgentPromptStrategy.default_configuration.model_copy( + os_config = OneShotAgentPromptStrategy.default_configuration.model_copy( deep=True ) - config.use_prefill = use_prefill - return OneShotAgentPromptStrategy(config, logger) + os_config.use_prefill = use_prefill + return OneShotAgentPromptStrategy(os_config, logger) diff --git a/classic/original_autogpt/autogpt/agents/prompt_strategies/plan_execute.py b/classic/original_autogpt/autogpt/agents/prompt_strategies/plan_execute.py index 23f4abe19f..dfd28dd0f8 100644 --- a/classic/original_autogpt/autogpt/agents/prompt_strategies/plan_execute.py +++ b/classic/original_autogpt/autogpt/agents/prompt_strategies/plan_execute.py @@ -141,7 +141,7 @@ class PlanExecuteActionProposal(ActionProposal): Note: plan and phase are stored in strategy state, not in the proposal. """ - thoughts: PlanExecuteThoughts + thoughts: PlanExecuteThoughts # type: ignore[assignment] class PlanExecutePromptConfiguration(BasePromptStrategyConfiguration): diff --git a/classic/original_autogpt/autogpt/agents/prompt_strategies/reflexion.py b/classic/original_autogpt/autogpt/agents/prompt_strategies/reflexion.py index c148679259..bec16113c6 100644 --- a/classic/original_autogpt/autogpt/agents/prompt_strategies/reflexion.py +++ b/classic/original_autogpt/autogpt/agents/prompt_strategies/reflexion.py @@ -115,7 +115,7 @@ class ReflexionActionProposal(ActionProposal): Note: phase and reflection_context are stored in strategy state. """ - thoughts: ReflexionThoughts + thoughts: ReflexionThoughts # type: ignore[assignment] class ReflexionPromptConfiguration(BasePromptStrategyConfiguration): diff --git a/classic/original_autogpt/autogpt/agents/prompt_strategies/rewoo.py b/classic/original_autogpt/autogpt/agents/prompt_strategies/rewoo.py index d7ef69ca8d..a4a7586339 100644 --- a/classic/original_autogpt/autogpt/agents/prompt_strategies/rewoo.py +++ b/classic/original_autogpt/autogpt/agents/prompt_strategies/rewoo.py @@ -135,7 +135,7 @@ class ReWOOActionProposal(ActionProposal): Note: plan, phase, is_synthesis are stored in strategy state, not in the proposal. """ - thoughts: ReWOOThoughts + thoughts: ReWOOThoughts # type: ignore[assignment] class ReWOOPromptConfiguration(BasePromptStrategyConfiguration): diff --git a/classic/original_autogpt/autogpt/agents/prompt_strategies/tree_of_thoughts.py b/classic/original_autogpt/autogpt/agents/prompt_strategies/tree_of_thoughts.py index 8e36929b83..12cd8372c9 100644 --- a/classic/original_autogpt/autogpt/agents/prompt_strategies/tree_of_thoughts.py +++ b/classic/original_autogpt/autogpt/agents/prompt_strategies/tree_of_thoughts.py @@ -223,7 +223,7 @@ class ToTActionProposal(ActionProposal): Note: thought_path, alternatives_explored, and phase are stored in strategy state. """ - thoughts: ToTThoughts + thoughts: ToTThoughts # type: ignore[assignment] class ToTPromptConfiguration(BasePromptStrategyConfiguration): diff --git a/classic/original_autogpt/autogpt/app/agent_protocol_server.py b/classic/original_autogpt/autogpt/app/agent_protocol_server.py index e4b2badae4..b900d3d403 100644 --- a/classic/original_autogpt/autogpt/app/agent_protocol_server.py +++ b/classic/original_autogpt/autogpt/app/agent_protocol_server.py @@ -299,7 +299,15 @@ class AgentProtocolServer: if last_proposal and last_proposal.use_tool.name != ASK_COMMAND else "" ) - output += f"{assistant_response.thoughts.speak}\n\n" + # Get speak text if available, otherwise use summary or string representation + thoughts = assistant_response.thoughts + if isinstance(thoughts, str): + thoughts_output = thoughts + elif hasattr(thoughts, "speak"): + thoughts_output = thoughts.speak # type: ignore[union-attr] + else: + thoughts_output = thoughts.summary() + output += f"{thoughts_output}\n\n" output += ( f"Next Command: {next_tool_to_use}" if next_tool_to_use.name != ASK_COMMAND diff --git a/classic/original_autogpt/autogpt/app/ui/protocol.py b/classic/original_autogpt/autogpt/app/ui/protocol.py index fa67c7d703..7fbf694485 100644 --- a/classic/original_autogpt/autogpt/app/ui/protocol.py +++ b/classic/original_autogpt/autogpt/app/ui/protocol.py @@ -11,7 +11,7 @@ from typing import TYPE_CHECKING, Any, AsyncIterator from forge.permissions import ApprovalScope if TYPE_CHECKING: - from autogpt.agents.prompt_strategies.one_shot import AssistantThoughts + from forge.models.utils import ModelWithSummary class MessageLevel(str, Enum): @@ -90,7 +90,7 @@ class UIProvider(ABC): async def display_thoughts( self, ai_name: str, - thoughts: "str | AssistantThoughts", + thoughts: "str | ModelWithSummary", speak_mode: bool = False, ) -> None: """Display the agent's thoughts. diff --git a/classic/original_autogpt/autogpt/app/ui/terminal/provider.py b/classic/original_autogpt/autogpt/app/ui/terminal/provider.py index 2a605d6e56..a567af677e 100644 --- a/classic/original_autogpt/autogpt/app/ui/terminal/provider.py +++ b/classic/original_autogpt/autogpt/app/ui/terminal/provider.py @@ -18,7 +18,7 @@ from forge.permissions import ApprovalScope from ..protocol import ApprovalResult, MessageLevel, UIProvider if TYPE_CHECKING: - from autogpt.agents.prompt_strategies.one_shot import AssistantThoughts + from forge.models.utils import ModelWithSummary class TerminalUIProvider(UIProvider): @@ -128,7 +128,7 @@ class TerminalUIProvider(UIProvider): async def display_thoughts( self, ai_name: str, - thoughts: "str | AssistantThoughts", + thoughts: "str | ModelWithSummary", speak_mode: bool = False, ) -> None: """Display the agent's thoughts.