{"record":{"id":"9bf52f63db6d5ae1","repo":"huggingface/smolagents","slug":"this-method-should-be-implemented-in-child-classes","errorCode":null,"errorMessage":"This method should be implemented in child classes","messagePattern":"This method should be implemented in child classes","errorType":"exception","errorClass":"NotImplementedError","httpStatus":null,"severity":"critical","filePath":"src/smolagents/agents.py","lineNumber":780,"sourceCode":"        \"\"\"\n        Reads past llm_outputs, actions, and observations or errors from the memory into a series of messages\n        that can be used as input to the LLM. Adds a number of keywords (such as PLAN, error, etc) to help\n        the LLM.\n        \"\"\"\n        messages = self.memory.system_prompt.to_messages(summary_mode=summary_mode)\n        for memory_step in self.memory.steps:\n            messages.extend(memory_step.to_messages(summary_mode=summary_mode))\n        return messages\n\n    def _step_stream(\n        self, memory_step: ActionStep\n    ) -> Generator[ChatMessageStreamDelta | ToolCall | ToolOutput | ActionOutput]:\n        \"\"\"\n        Perform one step in the ReAct framework: the agent thinks, acts, and observes the result.\n        Yields ChatMessageStreamDelta during the run if streaming is enabled.\n        At the end, yields either None if the step is not final, or the final answer.\n        \"\"\"\n        raise NotImplementedError(\"This method should be implemented in child classes\")\n\n    def step(self, memory_step: ActionStep) -> Any:\n        \"\"\"\n        Perform one step in the ReAct framework: the agent thinks, acts, and observes the result.\n        Returns either None if the step is not final, or the final answer.\n        \"\"\"\n        return list(self._step_stream(memory_step))[-1]\n\n    def extract_action(self, model_output: str, split_token: str) -> tuple[str, str]:\n        \"\"\"\n        Parse action from the LLM output\n\n        Args:\n            model_output (`str`): Output of the LLM\n            split_token (`str`): Separator for the action. Should match the example in the system prompt.\n        \"\"\"\n        try:\n            split = model_output.split(split_token)","sourceCodeStart":762,"sourceCodeEnd":798,"githubUrl":"https://github.com/huggingface/smolagents/blob/30bb1161095dbae2271e6bc3cc4c219cc3897a57/src/smolagents/agents.py#L762-L798","documentation":"MultiStepAgent is an abstract base class: its _step_stream method just raises NotImplementedError('This method should be implemented in child classes'). Each concrete agent (ToolCallingAgent, CodeAgent) overrides it to define its ReAct step behavior.","triggerScenarios":"Instantiating MultiStepAgent directly and calling run()/step(), or subclassing MultiStepAgent without overriding _step_stream; also calling super()._step_stream(...) from a subclass override.","commonSituations":"Creating a custom agent type by extending MultiStepAgent and forgetting to implement the step logic; refactorings that rename the override or accidentally call the parent implementation.","solutions":["Don't instantiate MultiStepAgent directly; use CodeAgent or ToolCallingAgent","In your subclass, implement _step_stream as a generator yielding ChatMessageStreamDelta/ToolCall/ToolOutput and finally an ActionOutput","Model your subclass on ToolCallingAgent's implementation or delegate by composition instead of inheritance"],"exampleFix":"# before\nclass MyAgent(MultiStepAgent):\n    def _do_step(self): ...  # wrong name; _step_stream left abstract\n\n# after\nclass MyAgent(MultiStepAgent):\n    def _step_stream(self):\n        # think / act / observe logic\n        yield ActionOutput(output=result, is_final_answer=done)","handlingStrategy":"validation","validationCode":"import inspect\n\ndef assert_concrete(agent_cls):\n    if inspect.isabstract(agent_cls) or agent_cls._step_stream is MultiStepAgent._step_stream:\n        raise TypeError(f\"{agent_cls.__name__} must implement _step_stream\")","typeGuard":"def implements_step_stream(cls) -> bool:\n    return '_step_stream' in cls.__dict__ or any('_step_stream' in c.__dict__ for c in cls.__mro__[1:-1]) and cls.__dict__.get('_step_stream') is not None","tryCatchPattern":null,"preventionTips":["Prefer instantiating CodeAgent/ToolCallingAgent over subclassing MultiStepAgent","When subclassing, copy method signatures from ToolCallingAgent exactly"],"tags":["smolagents","abstract-method","notimplementederror","subclassing"],"backgroundTag":"abstract-method-not-implemented","analyzedSha":"30bb1161095dbae2271e6bc3cc4c219cc3897a57","analyzedAt":"2026-08-28T18:52:54.169Z","schemaVersion":2},"datasetVersion":"2026-08-28T21:17:43.275Z"}