Skip to content

⚙️ Protocols

Protocols are interfaces implemented by Components used to group related functionality. Each protocol needs to be handled explicitly by the agent at some point of the execution. We provide a comprehensive list of built-in protocols that are already handled in the built-in Agent, so when you inherit from the base agent all built-in protocols will work!

Protocols are listed in the order of the default execution.

Order-independent protocols

Components implementing exclusively order-independent protocols can added in any order, including in-between ordered protocols.


Yields constraints, resources and best practices for the agent. This has no direct impact on other protocols; is purely informational and will be passed to a llm when the prompt is built.

class DirectiveProvider(AgentComponent):
    def get_constraints(self) -> Iterator[str]:
        return iter([])

    def get_resources(self) -> Iterator[str]:
        return iter([])

    def get_best_practices(self) -> Iterator[str]:
        return iter([])

Example A web-search component can provide a resource information. Keep in mind that this actually doesn't allow the agent to access the internet. To do this a relevant Command needs to be provided.

class WebSearchComponent(DirectiveProvider):
    def get_resources(self) -> Iterator[str]:
        yield "Internet access for searches and information gathering."
    # We can skip "get_constraints" and "get_best_practices" if they aren't needed


Provides a command that can be executed by the agent.

class CommandProvider(AgentComponent):
    def get_commands(self) -> Iterator[Command]:

The easiest way to provide a command is to use command decorator on a component method and then yield the method. Each command needs a name, description and a parameter schema using JSONSchema. By default method name is used as a command name, and first part of docstring for the description (before Args: or Returns:) and schema can be provided in the decorator.

Example Calculator component that can perform multiplication. Agent is able to call this command if it's relevant to a current task and will see the returned result.

from forge.agent import CommandProvider, Component
from forge.command import command
from forge.models.json_schema import JSONSchema

class CalculatorComponent(CommandProvider):
    get_commands(self) -> Iterator[Command]:
        yield self.multiply

            "a": JSONSchema(
                description="The first number",
            "b": JSONSchema(
                description="The second number",
    def multiply(self, a: int, b: int) -> str:
        Multiplies two numbers.

            a: First number
            b: Second number

            Result of multiplication
        return str(a * b)

The agent will be able to call this command, named multiply with two arguments and will receive the result. The command description will be: Multiplies two numbers.

To learn more about commands see 🛠️ Commands.

Order-dependent protocols

The order of components implementing order-dependent protocols is important. Some components may depend on the results of components before them.


Yields messages that will be added to the agent's prompt. You can use either ChatMessage.user(): this will interpreted as a user-sent message or ChatMessage.system(): that will be more important.

class MessageProvider(AgentComponent):
    def get_messages(self) -> Iterator[ChatMessage]:

Example Component that provides a message to the agent's prompt.

class HelloComponent(MessageProvider):
    def get_messages(self) -> Iterator[ChatMessage]:
        yield ChatMessage.user("Hello World!")


Protocol called after the response is parsed.

class AfterParse(AgentComponent):
    def after_parse(self, response: ThoughtProcessOutput) -> None:

Example Component that logs the response after it's parsed.

class LoggerComponent(AfterParse):
    def after_parse(self, response: ThoughtProcessOutput) -> None:"Response: {response}")


Protocol called when the execution of the command fails.

class ExecutionFailure(AgentComponent):
    def execution_failure(self, error: Exception) -> None:

Example Component that logs the error when the command fails.

class LoggerComponent(ExecutionFailure):
    def execution_failure(self, error: Exception) -> None:
        logger.error(f"Command execution failed: {error}")


Protocol called after the command is successfully executed by the agent.

class AfterExecute(AgentComponent):
    def after_execute(self, result: ActionResult) -> None:

Example Component that logs the result after the command is executed.

class LoggerComponent(AfterExecute):
    def after_execute(self, result: ActionResult) -> None:"Result: {result}")