2026-01-27 00:28:29 +00:00
< ? php
declare ( strict_types = 1 );
2026-01-27 16:12:58 +00:00
namespace Core\Mod\Agentic\Mcp\Tools\Agent\Session ;
2026-01-27 00:28:29 +00:00
2026-01-27 17:34:46 +00:00
use Core\Mcp\Dependencies\ToolDependency ;
2026-01-27 16:12:58 +00:00
use Core\Mod\Agentic\Mcp\Tools\Agent\AgentTool ;
use Core\Mod\Agentic\Models\AgentPlan ;
use Core\Mod\Agentic\Models\AgentSession ;
2026-02-23 03:50:09 +00:00
use Illuminate\Support\Str ;
2026-01-27 00:28:29 +00:00
/**
* Start a new agent session for a plan .
*/
class SessionStart extends AgentTool
{
protected string $category = 'session' ;
protected array $scopes = [ 'write' ];
/**
* Get the dependencies for this tool .
*
* Workspace context is needed unless a plan_slug is provided
* ( in which case workspace is inferred from the plan ) .
*
* @ return array < ToolDependency >
*/
public function dependencies () : array
{
// Soft dependency - workspace can come from plan
return [
ToolDependency :: contextExists ( 'workspace_id' , 'Workspace context required (or provide plan_slug)' )
-> asOptional (),
];
}
public function name () : string
{
return 'session_start' ;
}
public function description () : string
{
return 'Start a new agent session for a plan' ;
}
public function inputSchema () : array
{
return [
'type' => 'object' ,
'properties' => [
'plan_slug' => [
'type' => 'string' ,
'description' => 'Plan slug identifier' ,
],
'agent_type' => [
'type' => 'string' ,
'description' => 'Type of agent (e.g., opus, sonnet, haiku)' ,
],
'context' => [
'type' => 'object' ,
'description' => 'Initial session context' ,
],
],
'required' => [ 'agent_type' ],
];
}
public function handle ( array $args , array $context = []) : array
{
try {
$agentType = $this -> require ( $args , 'agent_type' );
} catch ( \InvalidArgumentException $e ) {
return $this -> error ( $e -> getMessage ());
}
// Use circuit breaker for Agentic module database calls
return $this -> withCircuitBreaker ( 'agentic' , function () use ( $args , $context , $agentType ) {
$plan = null ;
if ( ! empty ( $args [ 'plan_slug' ])) {
$plan = AgentPlan :: where ( 'slug' , $args [ 'plan_slug' ]) -> first ();
}
$sessionId = 'ses_' . Str :: random ( 12 );
// Determine workspace_id - never fall back to hardcoded value in multi-tenant environment
$workspaceId = $context [ 'workspace_id' ] ? ? $plan ? -> workspace_id ? ? null ;
if ( $workspaceId === null ) {
2026-02-23 11:28:32 +00:00
return $this -> error ( 'workspace_id is required. Ensure you have authenticated with a valid API key and started a session, or provide a valid plan_slug to infer workspace context. See: https://host.uk.com/ai' );
2026-01-27 00:28:29 +00:00
}
$session = AgentSession :: create ([
'session_id' => $sessionId ,
'agent_plan_id' => $plan ? -> id ,
'workspace_id' => $workspaceId ,
'agent_type' => $agentType ,
'status' => 'active' ,
'started_at' => now (),
'last_active_at' => now (),
'context_summary' => $args [ 'context' ] ? ? [],
'work_log' => [],
'artifacts' => [],
]);
return $this -> success ([
'session' => [
'session_id' => $session -> session_id ,
'agent_type' => $session -> agent_type ,
'plan' => $plan ? -> slug ,
'status' => $session -> status ,
],
]);
}, fn () => $this -> error ( 'Agentic service temporarily unavailable. Session cannot be created.' , 'service_unavailable' ));
}
}