Skip to main content

What’s New

SessionRuntime::create() — single entry point for session creation

SessionRuntime now exposes a create(AgentDefinition $definition, ?AgentState $seed = null) method that handles the full session creation lifecycle: instantiation, hook processing, persistence, and event emission — all in one call. Before:
$stateFactory = new DefinitionStateFactory();
$sessionFactory = new SessionFactory($stateFactory);
$session = $repo->create($sessionFactory->create($definition));
After:
$session = $runtime->create($definition);
The new method runs through the same hook and event pipeline as execute(), so session controllers fire consistently for both creation and updates.

Dedicated BeforeCreate / AfterCreate hook stages

The AgentSessionStage enum gains two new cases: BeforeCreate and AfterCreate. During SessionRuntime::create(), hooks fire in this order:
  1. BeforeCreate — create-only pre-persist logic (e.g. set defaults, assign IDs)
  2. BeforeSave — shared pre-persist logic (fires on both create and execute)
  3. persist
  4. AfterSave — shared post-persist logic (fires on both create and execute)
  5. AfterCreate — create-only post-persist logic (e.g. send notifications)
The execute() pipeline is unchanged — it continues to fire only BeforeSave / AfterSave. This layered approach (inspired by Eloquent’s creating/saving/saved/created events) lets hooks distinguish between first-time creation and subsequent updates.

SessionFactory is now injectable

SessionRuntime accepts an optional ?SessionFactory constructor parameter. It defaults to new SessionFactory(new DefinitionStateFactory()) when omitted, so existing call sites are unaffected — but custom state factories can now be injected for testing or advanced use cases.

CanManageAgentSessions contract updated

The CanManageAgentSessions interface now includes create():
interface CanManageAgentSessions
{
    public function create(AgentDefinition $definition, ?AgentState $seed = null): AgentSession;
    public function listSessions(): SessionInfoList;
    public function getSessionInfo(SessionId $sessionId): AgentSessionInfo;
    public function getSession(SessionId $sessionId): AgentSession;
    public function execute(SessionId $sessionId, CanExecuteSessionAction $action): AgentSession;
}

When to use SessionFactory + repo directly

SessionFactory and SessionRepository::create() remain available for the one case where you already have a fully constructed AgentSession — forking. ForkSession returns a concrete session instance, so you persist that branch via $repo->create($forked) rather than going through SessionRuntime::create().