For the complete documentation index, see llms.txt. This page is also available as Markdown.

Upgrade

Upgrade to v4 from v3

In this new major version the public APIs of Neuron components weren't changed dramatically (we minimized the impact as much as possible). We've focused on improving the most important component on which the entire framework is based, Workflow. Since it's the foundation of the entire architecture, the changes implemented in this new version may impact your code, especially if you use advanced patterns like interrupts and persistence.

We also took advantage of this release to fix other critical issues emerged in the v3 like the Tool Approval flow in the Agent, and other design improvements to have more freedom to evolve the framework with less breaking changes in the future.

We continue to work to provide the best possible developer experience, to help you create successful AI products in PHP.

Updating Dependencies

You should update the following dependencies in your application's composer.json file:

{
    "repositories": [
        {
            "type": "vcs",
            "url": "https://github.com/neuron-core/neuron-ai"
        }
    ],
    "require": {
        ...,
        "neuron-core/neuron-ai": "4.x-dev"
    },
}

The inspector-php package was removed from default dependencies. So you have to install it in your application if you want to connect your agent to the Inspector monitoring dashboard:

High Impact Changes

Agent return type

In this new major version the Agent entity was subject to a substantial refactor in order to eliminate many frictions for advanced use cases, and make the agent class more usable as a normal Workflow from which it inherits.

The most important impact is the return type. The Agent return an instance of the AgentState that is an extension of the underlying WorkflowState with a couple of helper methods to keep as much as possible the external APIs seen by your application unchanged.

The most impactful change is in the stream() method. Without the AgentHandler the method return the generator directly.

If you interact with frontend protocol, you now must pass the stream adapter as second parameter of the stream() method.

nothing change for structured() and chat().

Tool becomes fully abstract

The Tool class is no longer a concrete class and can no longer be used directly. Its design is now intended to be extendable, allowing you to implement your own tools with less code and more flexibility.

We also removed the constructor from the abstract class so you can specify tool name and description as normal class properties instead of calling the parent constructor. You are free to use a class constructor only if you want to pass external dependencies to the tool:

Remove WorkflowHandler

The Workflow component was subject of an important refactoring in order to simplify its usage and public APIs. Working with Workflow in the previous version, you were need to call the init() method to get the WorkflowHandler instance and than call run() or events() on the handler to finally execute the workflow:

Following a drastic simplification of the workflow execution logic, the handler is no longer necessary and it is possible to invoke the two methods run() and events() directly in the workflow.

Workflow Interrupt/Resume

The architecture of the workflow execution and its interruption capabilities was redisigned to make it easier to manage interruption and tool approval, but also open the doors for the implementation of durable, crash proof, agentic workflows.

Remove WorkflowInterrupt exception

In case of interruption the Workflow doesn't throw the special WorkflowException to inform the caller script about the interruption. It just return an "interrupted" state:

No more try/catch block.

This change the Tool Approval flow. Check out the documentation in case you are using this middleware in your agents.

Resume Payload as plain array

The interruption request you propagate from the node is now only a signal to carry information from the node to the outside caller script. To resume the workflow you no longer need to pass the request back to the workflow. The resume payload is now just a simple array:

Agent Instructions

Agent instructions must be an instance of a SystemMessage. You can just pass the string to the constructor to make it compatible with this new version:

Tool Approval

The tool approval flow was entirely rewritten. The Agent class now manages the entire process. You just need to take care of rendering the UI so users can decide whether to approve or reject a tool call.

The status of tools requiring approval is stored into the chat history within the last ToolCallMessage. This allows you to design the UI to just render the messages in the chat history, and when it meets a ToolCallMessage you can check the approval status of the tools to show the Approve/Deny actions, or the normal tool call already happened.

Tool Approval

New Tool requiresApproval() method

We introduced the requiresApproval() method on the Tool class to determine whether approval is needed based on the tool call's arguments:

To activate the tool approval flow you always need to attach the ToolApproval middleware to the Agent. Custom approval policy on the middleware have precedence over the one defined in the tool's requiresApproval() method.

Database Schema For Workflow Persistence

Due to the changes in the workflow execution model, the database schema for persistence across interruptions has been changed to support the new features. Check out the dedicated section to get ready to run SQL queries to start with the new database format.

Persistence

Medium Impact

Monitoring

The framework is transitioning to the PSR-14 Event Dispatcher interface, instead of the PHP native \SplObserver. We kept the existing interfaces in place, and also the LogObserver usgin adapters, but they are marked as @deprecated.

This will make it easier to integrate Neuron agents and agentic workflows in general with other existing frameworks and applications.

Monitoring

Providers return ProviderResponse

AI provider methods chat() and stream() now return ProviderResponse instead of Message. The ProviderResponse wraps the assistant message and provides access to the raw HTTP response body and headers.

This only affects standalone provider usage. When providers are used inside an Agent (via chat(), stream(), or structured() on the Agent itself), no changes are needed — the Agent handles the ProviderResponse internally.

You only need to refactor code that calls provider methods directly, such as in scripts, controllers, commands, or custom workflows.

Changes on AIProviderInterface

We removed messageMapper() and toolPayloadMapper() from the AIProviderInterface, and the new getModel() methos was introduced. If you have any custom provider implementation that directly use this interface, you need to adjust it properly.

Last updated