Neuron AI V4.0: Workflow Refactor, Streaming Overhaul & Breaking Changes for PHP AI Agents
Neuron AI V4.0 introduces a major workflow refactor, breaking changes to Agent streaming and tool approval, removes WorkflowHandler, adds AG-UI events and streaming channels, and provides an AI-assisted upgrade guide for PHP developers building AI agents.
Upgrade Overview: From V3 to V4
Neuron AI V4.0 focuses on refactoring the core foundation — the Workflow system — while minimizing disruptive changes to the public API. The release addresses key issues from V3 (e.g., tool approval flow in Agents) and improves architectural design to reduce future breaking changes. Developers using Tool Approval, Interruption, or Streaming Adapters are strongly encouraged to use AI coding agents (Codex, Claude Code) with the official upgrade guide located at vendor/neuron-core/neuron-ai/upgrade.
Dependency Updates
Update the core dependency in composer.json:
{
"require": {
"neuron-core/neuron-ai": "^4.0"
}
}Removed Default Dependency
inspector-phpis no longer a default dependency. To connect Agents to Inspector monitoring and APM, manually require:
composer require inspector-apm/inspector-phpHigh-Impact Changes
1. New Agentic Skills for AI Coding Agents
Skills for AI coding agents have been completely rewritten to reflect V4 features. Delete old skill directories (e.g., .claude, .agent) and reconfigure using the official installation guide.
2. Agent Return Type & Streaming Refactor
Agent entities underwent major refactoring to align with Workflow usability:
Return type change : Agents now return AgentState instances (extends WorkflowState with helper methods for backward compatibility).
stream() method overhaul : Removed AgentHandler; stream() now directly returns a Generator.
Example usage:
foreach ($agent->stream(new UserMessage("Hello")) as $event) {
if ($event instanceof TextChunk) {
echo $event->content;
}
}Frontend streaming protocol adaptation : Register an adapter manually on the Agent instance:
$generator = MyAgent::make()
->setStreamAdapter(new AGUIAdapter('thread_id'))
->stream(new UserMessage("Hello"));
foreach ($generator as $event) {
echo $event;
ob_flush();
flush();
}Note: structured() and chat() invocation methods remain unchanged.
3. Tool Class Becomes Pure Abstract
Toolis now abstract and cannot be instantiated directly; must be extended. Changes:
Removed abstract class constructor.
Tool name ( $name) and description ( $description) are defined as regular class properties; no need to call parent::__construct(). Only define a constructor when injecting external dependencies.
Example:
class MyTool extends Tool {
protected string $name = 'my_tool';
protected ?string $description = 'What the tool does.';
public function __construct(protected string $apiKey) {}
public function __invoke() {
// tool business logic
}
}4. Complete Removal of WorkflowHandler
Workflow execution simplified: no longer need init() to get a WorkflowHandler. Call run() or events() directly on the workflow instance.
V3 (old):
$handler = MyWorkflow::make()->init();
// single run
$finalState = $handler->run();
// event stream
foreach ($handler->events() as $chunk) { /* ... */ }
$finalState = $handler->getResult();V4 (new):
// single run
$finalState = MyWorkflow::make()->run();
// event stream
$generator = MyWorkflow::make()->events();
foreach ($generator as $chunk) { /* ... */ }
$finalState = $generator->getResult();5. Workflow Interruption & Resumption Architecture Redesign
Redesigned interruption and resumption to enable durable, crash-proof production workflows.
▪ Removed WorkflowInterrupt Exception
Workflows no longer throw a special WorkflowException on interruption; they return a state object marked as interrupted. No try/catch needed:
$state = $workflow->run();
if ($state->isInterrupted()) {
$request = $state->getInterruptRequest();
$workflowId = $workflow->getWorkflowId();
}▪ Resumption Payload Simplified to Plain Array
Interrupt requests from nodes are now signals. Resume by passing a plain array:
// Node triggers interruption
class InterruptableNode extends Node {
public function __invoke(FirstEvent $event, WorkflowState $state): NextEvent {
$payload = $this->interrupt(new ApprovalRequest('human input needed'));
$state->set('received_feedback', $payload);
return new NextEvent();
}
}
// External resume: pass array directly
$payload = ['action_id' => 'approve'];
$finalState = $workflow->resume($payload);6. Agent Instructions Strong Typing
Agent instructions must now be SystemMessage instances. Pass the prompt string to the constructor:
use NeuronAI\Chat\Messages\SystemMessage;
class YouTubeAgent extends Agent {
protected function provider(): AIProviderInterface { /* ... */ }
protected function instructions(): SystemMessage {
return new SystemMessage(
"You are an AI Agent specialized in writing YouTube video summaries"
);
}
}7. Tool Approval Mechanism Fully Rewritten
Agent now manages the full tool approval flow; developers only handle frontend UI rendering (approve/reject buttons).
Pending approval tool state stored in the last ToolCallMessage of chat history.
Frontend renders chat history sequentially; when encountering a ToolCallMessage, check its approval status to show actions.
New requiresApproval() Dynamic Method
Tools can implement requiresApproval(array $inputs): bool to decide approval based on actual model-provided arguments:
class MyTool extends Tool {
public function requiresApproval(array $inputs): bool {
// e.g., only require approval when amount > 100
return $inputs['amount'] > 100;
}
}Note: Requires ToolApproval middleware on the Agent. Middleware custom rules take precedence over the tool's own requiresApproval .
8. Workflow Persistence Database Schema Changes
Due to execution model refactor, persistence table structures changed. If persistence is enabled, run the official SQL migrations.
9. Removed Guzzle Hard Dependency, Switched to Native cURL
Before : Required guzzlehttp/guzzle as HTTP client.
Now : Built-in CurlHttpClient with zero external Composer dependencies; only needs PHP's ext-curl (enabled by default).
Note : If you explicitly pass a custom GuzzleHttpClient instance, manually run composer require guzzlehttp/guzzle.
10. Vector Store Native Filter Support
VectorStoreInterfacerefactored to support native filtering; method names and signatures changed. Custom vector store implementations must update signatures.
11. Calculator Toolkit Refactor & Token Optimization
Previously, models poorly composed calls to add, subtract, multiply etc., wasting tokens. V4 consolidates into a single Evaluate tool: model outputs a full math expression, tool parses and returns result in one step, drastically reducing context and token usage.
12. Chat History & Storage Decoupling
Two goals: (1) separate message storage from session context window management; (2) simplify Neuron integration with business systems.
Removed ChatHistoryInterface, introduced MessageStoreInterface.
Archive only, never delete : Messages exceeding context window are marked archived (not physically deleted). LLM receives trimmed active context; database retains full history.
13. Middleware Method Signature Adjustment
Workflow engine supports transient Resources (tool sets, system instructions, chat history) not persisted during interruption. Middleware before and after now receive a $resources parameter:
interface WorkflowMiddleware {
public function before(
NodeInterface $node,
Event $event,
WorkflowState $state,
WorkflowResources $resources // new
): void;
public function after(
NodeInterface $node,
Event $result,
WorkflowState $state,
WorkflowResources $resources // new
): void;
}14. ReaderInterface Contract Change
File reader interface replaced static getText() with instance method read() to support constructor dependency injection:
interface ReaderInterface {
public function read(string $filePath): string;
}Medium-Impact Changes
1. Monitoring & Event Dispatcher Migrating to PSR-14
Observability moving from native PHP \SplObserver to standard PSR-14 Event Dispatcher . Legacy observer interfaces and LogObserver retained but marked @deprecated, greatly improving integration with modern PHP frameworks.
2. AI Provider Unified ProviderResponse Return
Provider chat() and stream() now return ProviderResponse objects (not raw Message). Allows access to assistant message, raw HTTP response body ( body()), and headers ( headers()). Affects only code directly calling Providers outside Agent internals.
$response = $provider->chat(new UserMessage(...));
$response->message(); // assistant message
$response->body(); // raw response body
$response->headers(); // response headers3. AIProviderInterface Tweaks
Removed redundant messageMapper() and toolPayloadMapper(); added getModel(). Custom Provider implementations must adapt.
New Features
1. AG-UI Custom Event Support
Native support for STEP_STARTED, STEP_FINISHED, ACTIVITY_SNAPSHOT, CUSTOM frontend events. Supports Vercel-spec transient data-* fragments so intermediate business info streams to frontend without polluting history context.
2. Streaming Channels (Breaking HTTP Limits)
Complex, long-running Agent chains often hit HTTP timeouts. V4 introduces Channels : stream Agent/Workflow output out of HTTP lifecycle directly to Pusher, WebSocket, Redis queues or other long-lived connection services, then push to frontend.
3. Automatic Event Fragmentation for Streaming
Real-time push services (Pusher, Laravel Reverb, Soketi) impose message size limits (e.g., 10KB–100KB). Neuron now auto-fragments large tool results or snapshots into sequential fragments. Companion front-end SDK: TypeScript NPM package @neuron-core/streaming handles out-of-order reassembly and stream restoration.
4. Cross-Session Semantic Long-Term Memory
Agents gain cross-session long-term memory via SemanticMemoryRetrieval component, automatically storing and retrieving user preferences, background info, and historical focus across multiple conversations.
5. Interruptible HTTP Client
When user clicks "Stop generating", the in-flight streaming transfer can be interrupted at network layer; already-generated text chunks are preserved and properly stored in chat history.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
Open Source Tech Hub
Sharing cutting-edge internet technologies and practical AI resources.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
